Querying by a pod field - php

I have a custom pod, product_type, in that pod I have a custom field named label. I want to find all the pods where the label matches a certain strings.
Iv been trying this (and some other variations):
$mypod = pods('product_type', array(
'where' => 'product_type.label LIKE "%'.$someLabelString.'%"',
'limit'=>-1
));
I've also tried changing the product_type.label part of the query to t.label, but to no avail. I get this error:
Database Error; SQL: SELECT DISTINCT `t`.* FROM `wp_posts` AS `t` WHERE ( ( `product_type`.`label` LIKE "%hello%" ) AND ( `t`.`post_type` = "product_type" ) AND ( `t`.`post_status` IN ( "publish" ) ) ) ORDER BY `t`.`menu_order`, `t`.`post_title`, `t`.`post_date`; Response: Unknown column 'product_type.label' in 'where clause'

Here’s a super handy break down of what field syntax to use for each pod type:
http://pods.io/docs/code/pods/find/#additional-information
Custom simple lists consist of a label (for display) and a value (the underlying “raw” value). For the ‘where’ parameter, you probably need to check against whatever you set as the ‘value’.
When you create a simple custom defined list, a box becomes available for “Custom Defined Options”. As the help pop-up says: “One option per line, use value|Label for separate values and labels”
If you added the label field to your pod, you would just use product_type.label if your pod is table-based for storage, otherwise if it’s meta-based you would use label.meta_value

Related

Execute category search Sphinx php

Good time of day!
There is such config Sphinx
source txtcontent : ru_config
{
sql_query = SELECT `id` as `txt_id`, 1 as index_id, `type_id`,`content_type_id`, `title`, `annonce`, `content` FROM `TxtContent` WHERE `status` = 1 AND `content_type_id` != 14
sql_attr_uint = index_id
sql_attr_uint = type_id
}
The entire table is indexed, and is stored in one large search index.
When it comes to find what is in it then all works OK
But today the task was to search for categories
The categories described in the field and have a type_id of type int
How in php using SphinxAPI to perform such a search?
Standard search looks like this.
$sphinxClient = new SphinxClient();
$sphinxClient->SetServer("127.0.0.1", 3312 );
$sphinxClient->SetLimits( 0, 700,700 );
$sphinxClient->SetSortMode(SPH_SORT_RELEVANCE);
$sphinxClient->SetArrayResult( true );
$result = $sphinxClient->Query( $this->query, 'txtcontent provider item');
I tried to add
$sphinxClient->SetFilter('type_id','1');
To search only where type_id = 1 but it didn't help.
Actually how can I search for a specific category? option to find everything in php to let go of the result excess is not considered (otherwise, the search will then be saturada existing limit) how to do it "properly" via the API without placing each topic in a separate search index?
setFilter takes an Array of values. And they need to be numeric (type_id is a numeric attribute)
$sphinxClient->SetFilter('type_id',array(1));
The sphinxapi class actully uses assertions to detect invalid data like this, which I guess you have disabled (otherwise would of seen them!).

enum values from mysql table

I have a enum column in my table and I am trying to get out the values I have set in the table in a drop down. So first I have written this query to get the column_type and column_name
"SELECT `COLUMN_NAME`,`DATA_TYPE`,`COLUMN_TYPE` FROM `INFORMATION_SCHEMA`.`COLUMNS` WHERE `TABLE_SCHEMA`='devsbh' AND `TABLE_NAME`='modules' AND `COLUMN_NAME` NOT IN ('created_at', 'updated_at')"
then I do this to get out the enum values like so
<?php
$regex = "/'(.*?)'/";
preg_match_all( $regex , $modules->COLUMN_TYPE , $enum_array );
$enum_fields = $enum_array[1];
?>
and I display like so
PS:Using laravel's blade template engine.
{!! Form::select($modules->COLUMN_NAME,$enum_fields) !!}
Everything is correct up until here. When I try to store it tries too save as for Y => 0 and for N => 1. How can I get the key => value same as enum value?
the values of $enum_fields as per the console is [0]=>Y , [1]=>N.
You can use the array_combine method to make the key and the value of the array same like so
<?php
$regex = "/'(.*?)'/";
preg_match_all( $regex , $modules->COLUMN_TYPE , $enum_array );
$keyValueSame = array_combine($enum_array[1],$enum_array[1]);
?>
now the key and value of the $keyValueSame array will have the same value.
the values of $keyValueSame as per the console is [Y]=>Y , [N]=>N.
You are probably better off just hard coding the enumerations into your codebase.
Assuming you are using MySQL, the idea behind enumerations is really to restrict the values in the column to a specific set - basically saying "if the value is not one of these strings, don't allow it.".
Enumerations are not designed to be changed often (if at all) - in fact, you may find issues if you do try to alter them it - it can take some database gymnastics to alter them especially if you have lots of records.
If your "lookup" data will change, and you need it to be database stored, make the column a foreign key to another table containing your lookup fields.
If you are stuck with the enumerations, just hard code the list in your dropdown.

MySQL "NOT IN" operator only uses the first number in the list?

Running a custom wordpress table to store notices to display to each individual site, I then store the dismissed notices as an option in the site's options table as a list (ie. 3,9,28,22)
Then, when loading the site I need to retrieve the site's notices excluding the ones already dismissed.
SELECT
*
FROM
be_notices as notice
WHERE
notice.id NOT IN ( SELECT option_value FROM wp_26_options WHERE option_name = 'be_dismissed_notices' )
The problem being it retrieves all the notices as expected, but excludes only the first number/id in the comma-separated list. If I put NOT IN (3,8) hardcoded it works. But that's exactly the value found in option_value so I am confused.
Any idea why it only excludes the first ID and not the second/other one(s)?
I used FIND_IN_SET = 0 instead.
WHERE ( FIND_IN_SET( notice.id, ( SELECT option_value FROM $table_options WHERE option_name = 'be_dismissed_notices' ) ) = 0 )
Solution 1 - antijoin (excluding LEFT JOIN):
SELECT notice.*
FROM be_notices as notice
LEFT JOIN wp_26_options as opt
ON opt.option_name = 'be_dismissed_notices'
AND FIND_IN_SET(notice.id, opt.option_value)
WHERE opt.id IS NULL
Solution 2 - NOT EXISTS:
SELECT notice.*
FROM be_notices as notice
WHERE NOT EXISTS (
SELECT 1
FROM wp_26_options as opt
WHERE opt.option_name = 'be_dismissed_notices'
AND FIND_IN_SET(notice.id, opt.option_value)
)
NOTE that a search with FIND_IN_SET() can not use an index and you will allways end up with a full table/index scan. Normalizing your tables might be a better solution.

PDOStatement::fetch() and duplicate field names

I'm working on a web application using MySQL and PHP 5.3.8. We have a mechanism to translate a simplified query instruction into a complete query string, including joins.
Since I cannot know what (normalized) tables there will be joined and what their fields are called, there may be duplicate field names. When executing PDOStatement::fetch(PDO::FETCH_ASSOC), I get an associated array of field names:
$test = $this->DBConnection->prepare("SELECT `events`.`Title`, `persons`.`Title` FROM `events` JOIN `persons` ON `events`.`HostID` = `persons`.`ID`;");
$test->execute();
$test->fetch();
But I have no way of distinguishing repeating field names, such as "title". Worse, duplicates overwrite each other:
array('Title' => 'Frodo Baggins');
In the bad old days, I ran mysql_fetch_field() on each field to get the table for each field. Please, tell me there is a better way than prefixing the fields (SELECT events.Title AS eventsTitle;).
Your help is greatly appreciated!
Give them aliases in the query so they won't be duplicates:
SELECT events.Title AS eTitle, persons.Title AS pTitle FROM ...
Then the row will be:
array('eTitle' => 'Hobbit Meeting', 'pTitle' => 'Frodo Baggins');
The alternative is to fetch the result as an indexed array rather than associative:
$test->fetch(PDO::FETCH_NUM);
Then you'll get:
array('Hobbit Meeting', 'Frodo Baggins');
and you can access them as $row[0] and $row[1].

Joining Customer on Attribute

I'm trying to filter my orders which are returned back by the magento API by a customer attribute. I tried several approaches but nothing seem to work.
I'm using Magento 1.4.1.1 atm and the api does this at the moment:
$billingAliasName = 'billing_o_a';
$shippingAliasName = 'shipping_o_a';
$collection = Mage::getModel("sales/order")->getCollection()
->addAttributeToSelect('*')
->addAddressFields()
->addExpressionFieldToSelect(
'billing_firstname', "{{billing_firstname}}", array('billing_firstname'=>"$billingAliasName.firstname")
)
->addExpressionFieldToSelect(
'billing_lastname', "{{billing_lastname}}", array('billing_lastname'=>"$billingAliasName.lastname")
)
->addExpressionFieldToSelect(
'shipping_firstname', "{{shipping_firstname}}", array('shipping_firstname'=>"$shippingAliasName.firstname")
)
->addExpressionFieldToSelect(
'shipping_lastname', "{{shipping_lastname}}", array('shipping_lastname'=>"$shippingAliasName.lastname")
)
->addExpressionFieldToSelect(
'billing_name',
"CONCAT({{billing_firstname}}, ' ', {{billing_lastname}})",
array('billing_firstname'=>"$billingAliasName.firstname", 'billing_lastname'=>"$billingAliasName.lastname")
)
->addExpressionFieldToSelect(
'shipping_name',
'CONCAT({{shipping_firstname}}, " ", {{shipping_lastname}})',
array('shipping_firstname'=>"$shippingAliasName.firstname", 'shipping_lastname'=>"$shippingAliasName.lastname")
);
Which is the default API call I guess. Now I just want to join a customer attribute called update - how do I achieve this simple task?
Or is this not possible on a flat table like sales_flat_order?
Whenever I need to do this I use something like:
Joining An EAV Table (With Attributes) To A Flat Table
It's not well optimised but you should be able to pick out the parts you need.
PS.
I think I'll explain what I mean by optimised since it's important. In the heart of the method is this bit:
->joinLeft(array($alias => $table),
'main_table.'.$mainTableForeignKey.' = '.$alias.'.entity_id and '.$alias.'.attribute_id = '.$attribute->getAttributeId(),
array($attribute->getAttributeCode() => $field)
);
If you know MySQL then you'll know it will only pick one index when joining a table, the more specific the better. In this case only the entity_id and attribute_id fields are being used so MySQL is restricted to those. Both columns are indexed but the cardinality is low.
If the condition also included the entity type then MySQL would have the choice of using IDX_BASE which indexes the columns entity_type_id,entity_id,attribute_id,store_id in that order (it needs to process them left to right). So something like this results in a much improved EAV performance - depending on how many rows on the 'left' table it could be several hundred- or thousand-fold better.
$alias.'.entity_type_id='.$entityType->getId().' AND main_table.'.$mainTableForeignKey.' = '.$alias.'.entity_id AND '.$alias.'.attribute_id = '.$attribute->getAttributeId().' AND '.$alias.'.store_id=0'

Categories