Laravel where query not working - sql

I've got this table
beds
id
name
size
room
status
hotel
created_at
updated_at
I need to filter all beds that belong to a certain room. In order to do so, I've coded this lines.
public function index()
{
//
$user = JWTAuth::parseToken()->authenticate();
$data = Input::get('room');
if( $data ){
$beds = Bed::where('room', '=', $data )->get();
}else{
$beds = Bed::where('hotel', '=', $user->hostel )->get();
}
foreach( $beds as $bed) {
return $bed->get( array('size','room', 'id') );
}
}
So, If i give it the room id, it should return me only that room's ones.
The thing is that it's returning all table entries.
Any ideas?
UPDATE
Fixed relations and tried this:
return Room::with('beds')->findOrFail($data)->beds;
Now it gives me the number of items.
How can I get the items?
UPDATE
This is the model's code:
class Room extends \Eloquent {
protected $fillable = array('beds', 'price', 'name', 'description','hotel');
public function beds(){
return $this->hasMany('Bed', 'id', 'room');
}
}
UPDATE
The var_dump for:
var_dump( Room::with('beds')->findOrFail($data)->beds );
is:
int(1)
UPDATE
So, the final code is the following.
controller
public function index()
{
//
$user = JWTAuth::parseToken()->authenticate();
$data = Input::get('room');
if( $data ){
$d = intval( $data );
return Bed::where('room', '=', $d )->get( array('size', 'room', 'id', 'name') );
}else{
return Bed::where('hotel', '=', $user->hostel )->get( array('size', 'room', 'id', 'name') );
}
}
model
class Room extends \Eloquent {
protected $fillable = array('beds', 'price', 'name', 'description','hotel');
public function camas(){
return $this->hasMany('Bed', 'room', 'id');
}
}
Thank you guys!

You have quite a few issues in your attempts:
return $bed->get( array('size', 'room', 'id') );
// runs SELECT size, room, id from `rooms`
so it returns all the rooms (why on earth would you like to do this in a foreach anyway?)
return $this->hasMany('Bed', 'id', 'room');
// should be:
return $this->hasMany('Bed', 'room', 'id');
protected $fillable = array('beds', ...
public function beds(){
this is conflict - you will never get a relations when calling $room->beds since you have a column beds on your table.
that said, this is what you need:
public function index()
{
$user = JWTAuth::parseToken()->authenticate();
if(Input::has('room')){
$query = Bed::where('room', '=', Input::get('room'));
}else{
$query = Bed::where('hotel', '=', $user->hostel);
}
return $query->get(['size', 'room', 'id']); // given you need only these columns
}

Try this and see if it works. If not, can you provide the var_dump of Input::get('room') and the structure of the the beds table?
public function index()
{
//
$user = JWTAuth::parseToken()->authenticate();
$data = Input::get('room');
if( $data ){
$beds = Bed::where('room', '=', $data );
}else{
$beds = Bed::where('hotel', '=', $user->hostel );
}
return $beds->get(['size','room', 'id'])->toArray();
}
Better yet if you want to get specific beds in a room and you have your relations set up correctly:
return Room::with('beds')->findOrFail($data)->beds;
EDIT
I saw your update. Are you sure its giving you a number of items, maybe there is one item and the number is the id of it. Can you verify? Please provide a vardump of it if thats not the case. Also can you post your code for the relations in the model?

Related

Create relation hasMany() with composite field

Have the relation in model Product :
public function getDiscount()
{
return $this->hasMany(Discount::className(), ['id' => 'available_discount']);
}
Model has field available_discount, that stores data as 1;2;3, where 1;2;3 is discount ids.
Query Product::find()->joinWith('discount d')->where(['d.id' => [1,2,3]])->all()return products with key discount = [].
How i can return discounts as relation with ID 1, 2, 3 ?
Try this:
public function getDiscounts()
{
$idsAsArray = explode(';', $this->available_discount);
$query = Discount::find()->where(['id' => $idsAsArray]);
$query->multiple = true;
return $query;
}
And then get them via:
$product->discounts; // returns Discount[]
$product->getDiscounts()->count(); // gets the count of discount models.

Sku not working in magento product update API

$result = $client->call($session, 'catalog_product.update', array('123', array(
'name' => 'Product333222'
)
)
);
Here '123' is the Sku of product. Sku is not working here in update Api.
If i give Product ID in place of Sku it is working fine.
So what is the Issue behind that.
If anyone Knows please let me know.
Thanks.
Magento is a bit dull here.
Long story short:
If you are using a numeric value without specifying an identification type its assuming you are doing your works on a product id. If you where to insert "abc" as a value (not numeric) it will be treated as if it were a SKU.
Best way to solve this is to use an identification type (in your case "SKU") in your api call.
Please see this for more info on using the identification type. http://www.magentocommerce.com/api/soap/catalog/catalogProduct/catalog_product.update.html
Or see: Magento 1.5, numeric SKUs and productIdentifierType
Short story long:
The following function gets called trough the api
app/code/core/Mage/Catalog/Model/Api/Resource.php
protected function _getProduct($productId, $store = null, $identifierType = null)
{
$product = Mage::helper('catalog/product')->getProduct($productId, $this->_getStoreId($store), $identifierType);
if (is_null($product->getId())) {
$this->_fault('product_not_exists');
}
return $product;
}
As you can see that function is calling the following function in the product helper:
public function getProduct($productId, $store, $identifierType = null) {
$loadByIdOnFalse = false;
if ($identifierType == null) {
if (is_string($productId) && !preg_match("/^[+-]?[1-9][0-9]*$|^0$/", $productId)) {
$identifierType = 'sku';
$loadByIdOnFalse = true;
} else {
$identifierType = 'id';
}
}
/** #var $product Mage_Catalog_Model_Product */
$product = Mage::getModel('catalog/product');
if ($store !== null) {
$product->setStoreId($store);
}
if ($identifierType == 'sku') {
$idBySku = $product->getIdBySku($productId);
if ($idBySku) {
$productId = $idBySku;
}
if ($loadByIdOnFalse) {
$identifierType = 'id';
}
}
if ($identifierType == 'id' && is_numeric($productId)) {
$productId = !is_float($productId) ? (int) $productId : 0;
$product->load($productId);
}
return $product;
}
Without specifying an $identifierType here and using a sku like '123' the thrid line is going to do a preg match with will result in true. Thus using its else function threating it as an ID in stead of sku.
In the end:
So, do your call like:
$result = $client->call($session, 'catalog_product.update', array('123', array(
'name' => 'Product333222'
), null, 'sku'));

Get raw sql from Phalcon query builder

Is it possible to extract raw sql query from the query builder instance in Phalcon? Something like this?
$queryBuilder = new Phalcon\Mvc\Model\Query\Builder();
$queryBuilder
->from(…)
->where(…);
$rawSql = $queryBuilder->hypotheticalGetRawQueryMethod();
By error and trial the below seems to working. Would be great if someone could confirm if there's a better way.
$queryBuilder = new Builder();
$queryBuilder->from(…)->where(…);
$intermediate = $queryBuilder->getQuery()->parse();
$dialect = DI::getDefault()->get('db')->getDialect();
$sql = $dialect->select($intermediate);
Edit: As of 2.0.3 you can do it super simple, see comment for full details:
$modelsManager->createBuilder()
->from('Some\Robots')
->getQuery()
->getSql()
you can use getRealSqlStatement() (or similar function name) on the DbAdapter. See http://docs.phalconphp.com/en/latest/api/Phalcon_Db_Adapter.html
According to documentation you can get this way the resulting sql query.
Or wait, this might not work on querybuilder. Otherwise you can setup low level query logging: http://docs.phalconphp.com/en/latest/reference/models.html#logging-low-level-sql-statements
$db = Phalcon\DI::getDefault()->getDb();
$sql = $db->getSQLStatement();
$vars = $db->getSQLVariables();
if ($vars) {
$keys = array();
$values = array();
foreach ($vars as $placeHolder=>$var) {
// fill array of placeholders
if (is_string($placeHolder)) {
$keys[] = '/:'.ltrim($placeHolder, ':').'/';
} else {
$keys[] = '/[?]/';
}
// fill array of values
// It makes sense to use RawValue only in INSERT and UPDATE queries and only as values
// in all other cases it will be inserted as a quoted string
if ((strpos($sql, 'INSERT') === 0 || strpos($sql, 'UPDATE') === 0) && $var instanceof \Phalcon\Db\RawValue) {
$var = $var->getValue();
} elseif (is_null($var)) {
$var = 'NULL';
} elseif (is_numeric($var)) {
$var = $var;
} else {
$var = '"'.$var.'"';
}
$values[] = $var;
}
$sql = preg_replace($keys, $values, $sql, 1);
}
More you can read there
The following is the common solution:
$result = $modelsManager->createBuilder()
->from(Foo::class)
->where('slug = :bar:', ['bar' => "some-slug"])
->getQuery()
->getSql();
But you might not expect to see the query without its values, like in:
die(print_r($result, true));
Array
(
[sql] => SELECT `foo`.`id`, `foo`.`slug` FROM `foo` WHERE `foo`.`slug` = :bar
[bind] => Array
(
[bar] => some-slug
)
[bindTypes] =>
)
So, this simple code might be useful:
public static function toSql(\Phalcon\Mvc\Model\Query\BuilderInterface $builder) : string
{
$data = $builder->getQuery()->getSql();
['sql' => $sql, 'bind' => $binds, 'bindTypes' => $bindTypes] = $data;
$finalSql = $sql;
foreach ($binds as $name => $value) {
$formattedValue = $value;
if (\is_object($value)) {
$formattedValue = (string)$value;
}
if (\is_string($formattedValue)) {
$formattedValue = sprintf("'%s'", $formattedValue);
}
$finalSql = str_replace(":$name", $formattedValue, $finalSql);
}
return $finalSql;
}
If you're using query builder then like given below then getPhql function can serve the purpose as per phalcon 3.4.4 version.
$queryBuilder = new Builder();
$queryBuilder->from(…)->where(…)->getQuery();
$queryBuilder->getPhql();
if (!function_exists("getParsedBuilderQuery")) {
/**
* #param \Phalcon\Mvc\Model\Query\BuilderInterface $builder
*
* #return null|string|string[]
*/
function getParsedBuilderQuery (\Phalcon\Mvc\Model\Query\BuilderInterface $builder) {
$dialect = Phalcon\Di::getDefault()->get('db')->getDialect();
$sql = $dialect->select($builder->getQuery()->parse());
foreach ($builder->getQuery()->getBindParams() as $key => $value) {
// For strings work fine. You can add other types below
$sql = preg_replace("/:?\s?($key)\s?:?/","'$value'",$sql);
}
return $sql;
}
}
Simple function that im using for debugging.

PHP PDO dynamically updating db table with multiple records to a specific user ID

/* Newbie need some help; I am creating a class to auto update my apps db record when instructed to, but I am consistently getting this message below, and for the heck of it, I just not seeing what I am doing wrong. Can someone please look at my codes for me? Thank you.
Warning: PDOStatement::bindParam() expects at least 2 parameters, 1 given in……..on line 331; that where the "else if(is_string($val)){" is located.
*/
// vars given
// DBDriver: MySQL
$myTable = 'seeYou';
$loginDate = NULL;
$ip = $_SERVER['REMOTE_ADDR'];
$date = #date('m/d/Y \a\\t h:i a');
$_id =1;
// data array
$idata = array("last_logged_in"=>$loginDate,
"login_date"=>$date,
"ip_addr"=>$ip
);
class name
{
///------------ other methods here---------///
/**
*--------------------------------------------
* Method - PDO: SET FIELD VALUE PLACEHOLDER
*--------------------------------------------
* #return fields with prefix as placeholder
*/
protected function set_fieldValPlaceHolders(array $data)
{
$set = '';
foreach($data as $field => $value)
{
$set .= $field .'= :'.$field . ',';
}
// remove the last comma
$set = substr($set, 0, -1);
return $set;
}
public function save($data=NULL, $_id = NULL, $rows= NULL, $dbTable= NULL)
{
//----------------- some other codes goes here ----------------//
$id = (int)$_id;
// update row with a specific id
if (isset($id) !== NULL && $rows === NULL)
{
$set = $this->set_fieldValPlaceHolders($data);
$sql = "UPDATE {$dbTable} SET {$set} WHERE user_id = :uid";
try
{
// Build the database statement
$_stmt = $this->_dbConn->prepare($sql);
$_stmt->bindValue(':uid',$id, PDO::PARAM_INT);
foreach ($data as $field => $val)
{
if(is_int($val)){
$_stmt->bindValue(':'.$field.'\', '.$val.', PDO::PARAM_INT');
}
else if(is_string($val)){
$_stmt->bindValue(':'.$field.'\', '.$val.', PDO::PARAM_STR');
}
else if(is_bool($val)){
$_stmt->bindValue(':'.$field.'\', '.$val.', PDO::PARAM_BOOL');
}
else if(is_null($val)){
$_stmt->bindValue(':'.$field.'\', '.$val="null".', PDO::PARAM_NULL');
}
else {
$_stmt->bindValue(':'.$field.'\', '.$val.', NULL');
}
$result = $_stmt->execute();
$num = $_stmt->rowCount();
}
}
catch(PDOException $e)
{
die('Error! The process failed while updating your record. <br /> Line #'.__LINE__ .' '.$e);
}
if ($result === true)
{
return true;
}
}
Check your bindValue calls: You give 1 parameter (a long string). It needs at least two. Check all the '
for example, it should be:
$_stmt->bindValue(':'.$field, $val, PDO::PARAM_INT);

How to get the options of a configurable attribute in Magento?

we want to export/import configurable products through the Magento-API in another system. What is important for us, are the values of the configurable products like a T-Shirt which has 3 colors (red, green and blue).
We receive the configurable attributes with the following function:
public function options($productId, $store = null, $identifierType = null)
{
$product = $this->_getProduct($productId, $store, $identifierType);
if (!$product->getId()) {
$this->_fault('not_exists');
}
$configurableAttributeCollection = $product->getTypeInstance()->getConfigurableAttributes();
$result = array();
foreach($configurableAttributeCollection as $attribute){
$result[$attribute->getProductAttribute()->getAttributeCode()] = $attribute->getProductAttribute()->getFrontend()->getLabel();
//Attr-Code: $attribute->getProductAttribute()->getAttributeCode()
//Attr-Label: $attribute->getProductAttribute()->getFrontend()->getLabel()
//Attr-Id: $attribute->getProductAttribute()->getId()
}
return $result;
}
But how is it possible to get the options used in that product (e.a. blue, green, red if the configurable attribute is "color") with the now available label/id from the configurable attribute which we got through the above function?
Answers are very appreciated!
Tim
Since we couldn't find a better solution, this is what I came up with:
public function options($productId, $store = null, $identifierType = null)
{
$_product = $this->_getProduct($productId, $store, $identifierType);
if (!$_product->getId()) {
$this->_fault('not_exists');
}
//Load all simple products
$products = array();
$allProducts = $_product->getTypeInstance(true)->getUsedProducts(null, $_product);
foreach ($allProducts as $product) {
if ($product->isSaleable()) {
$products[] = $product;
} else {
$products[] = $product;
}
}
//Load all used configurable attributes
$configurableAttributeCollection = $_product->getTypeInstance()->getConfigurableAttributes();
$result = array();
//Get combinations
foreach ($products as $product) {
$items = array();
foreach($configurableAttributeCollection as $attribute) {
$attrValue = $product->getResource()->getAttribute($attribute->getProductAttribute()->getAttributeCode())->getFrontend();
$attrCode = $attribute->getProductAttribute()->getAttributeCode();
$value = $attrValue->getValue($product);
$items[$attrCode] = $value[0];
}
$result[] = $items;
}
return $result;
}
Hope this helps anybody.
I'm not 100% sure that I understand the question ... assuming you want the values and labels for the configurable options for a specific product I assume this would work (tested on version 1.4.0.1)
public function options($productId, $store = null, $identifierType = null)
{
$product = $this->_getProduct($productId, $store, $identifierType);
if (!$product->getId()) {
$this->_fault('not_exists');
}
$configurableAttributeCollection = $product->getTypeInstance()->getConfigurableAttributes();
$result = array();
foreach($configurableAttributeCollection as $attribute){
$result[$attribute->getProductAttribute()->getAttributeCode()] = array(
$attribute->getProductAttribute()->getFrontend()->getLabel() => $attribute->getProductAttribute()->getSource()->getAllOptions()
);
//Attr-Code: $attribute->getProductAttribute()->getAttributeCode()
//Attr-Label: $attribute->getProductAttribute()->getFrontend()->getLabel()
//Attr-Id: $attribute->getProductAttribute()->getId()
}
return $result;
}
again not sure exactly what your looking for, but the $attribute->getProductAttribute()->getSource()->getAllOptions() function gave me the available options label and value.
Hope this helps. if not, let me where I misunderstood. Thanks!