TYPO3 extbase database query - typo3

I have an extbase database query like below.
$query = $this->createQuery();
$result = $query->statement("Select * FROM table1 WHERE hidden = 0 AND deleted = 0 AND (".$PublicationYears.") AND logo != '' ORDER BY uid ASC LIMIT 0, ".$iLimit." ")->execute();
return $result;
$PublicationYears = "ttra = '12' or ttra = '13' or ttra = '14'";
I converted this query as follows,
$query = $this->createQuery();
$query->getQuerySettings()->setRespectStoragePage(FALSE);
$query->matching( $query->logicalAnd(
$query->equals('deleted', 0),
$query->equals('hidden', 0)
));
$query->matching($query->logicalAnd($PublicationYears));
$query->matching($query->logicalNot(
$query->equals('logo', '')
));
$query->setOrderings(array('uid' => Tx_Extbase_Persistence_QueryInterface::ORDER_ASCENDING));
$query->setLimit((integer)$iLimit);
$Result = $query->execute();
return $Result;
But the resultant query does not contain the query part related to,
$query->matching($query->logicalAnd($PublicationYears));
I think there are also other mistakes in the above query.
Please help me to create correct query.
Thanks in advance.

first of all you dont need this
$query->matching( $query->logicalAnd(
$query->equals('deleted', 0),
$query->equals('hidden', 0)
));
disable fields are included in query from default according to setting of table in ext_tables.php
multiple matching will not work
cause your third matching
$query->matching($query->logicalNot(
$query->equals('logo', '')
));
is overwriting the matching() used before it
logicalAnd on string ? it won't work either
in your case you just need to put everything in logicalAnd do it like this
$constraints = array();
$subConstraints = array();
$subConstraints[] = $query->equals('ttra', 12);
$subConstraints[] = $query->equals('ttra', 13);
$subConstraints[] = $query->equals('ttra', 14);
$constraints[] = $query->logicalOr($subConstraints);
$constraints[] = $query->logicalNot(
$query->equals('logo', '')
));
$query->matching($query->logicalAnd($constraints));

For your PublicationYears values you have to make or query in matching like below:
I think it might work only for PublicationYears variable.
$query->matching($query->logicalAnd(
$query->logicalOr(
$query->equals('ttra', 12)
),
$query->logicalOr(
$query->equals('ttra', 13)
),
$query->logicalOr(
$query->equals('ttra', 14)
),
));

Related

Zend_Db_Select : multiple from clause

Hy,
I have some problem vith Zend_Db_Select.
I have 2 variable : category and city. These 2 variables may have a value or they may be unset.
So I verify:
$status = '`p`.status = 1';
if($catID){
$catSQL = "`p`.parent = {$catID}";
}else{
$catSQL = '1=1';
}
if($city){
$citySQL = "`pm`.`meta_key` = 'oras' and `pm`.`meta_value` = {$city}";
$citySelect = array('pm' => 'postsmeta');
$condCity = "`p`.`ID` = `pm`.`parent_id`";
}else{
$citySQL = '1=1';
$citySelect = NULL;
$condCity = '1=1';
}
Now here is my query:
$select = $db->select()
->from( array('p' => 'posts'))
->from($citySelect)
->where($status)
->where($catSQL)
->where($condCity)
->where($citySQL)
;
The problem is that if city is empty I have something like
$select = $db->select()
->from( array('p' => 'posts'))
->from('')
->where(1=1)
->where(1=1)
->where(1=1)
->where(1=1)
;
The questions is how can I remove from('') from my query if city is empty.
Thank you!
Simply,
$select = $db->select()
->from( array('p' => 'posts'));
if($someConditionIsTrue) {
$select->join($table, $condition);
}
$select->where('field_value = ?', 'value1');
if($someConditionIsTrue) {
$select->where('another_field = ?', 'value 2');
}
Hope it helps.
Please use this syntax $select->where('another_field = ?', 'value 2'); for proper escaping values to prevent SQL injections.

silverstripe dataobject searchable

I´m trying to have certain DataObjects (News) displayed in the default SearchResult Page. So the result should display normal Pages and News.
Is there an easy way to accomplish that in Silverstripe 3?
Or is it recommended to code it completely custom - I mean a custom controller/action which handles the search request and creates a result list, which I display then in a custom template?
I found this, but obviously search is disabled right now:
https://github.com/arambalakjian/DataObjects-as-Pages
Thx and regards,
Florian
I usually but together a custom search function after enabling FulltextSearchable. So in _config.php I would have
FulltextSearchable::enable();
Object::add_extension('NewsStory', "FulltextSearchable('Name,Content')");
replacing Name and Content with whatever DBField you want to be searchable. And each searchable DataObject have this in their class to enable search indexes (pretty sure this needs to be added and run dev/build before enabling the extension, and only works on MySQL DB).
static $create_table_options = array(
'MySQLDatabase' => 'ENGINE=MyISAM'
);
then in my PageController I have my custom searchForm and results functions.
Here is the search function that returns the search form, called with $search in the template:
public function search()
{
if($this->request && $this->request->requestVar('Search')) {
$searchText = $this->request->requestVar('Search');
}else{
$searchText = 'Search';
}
$f = new TextField('Search', false, $searchText);
$fields = new FieldList(
$f
);
$actions = new FieldList(
new FormAction('results', 'Go')
);
$form = new Form(
$this,
'search',
$fields,
$actions
);
//$form->disableSecurityToken();
$form->setFormMethod('GET');
$form->setTemplate('SearchForm');
return $form;
}
and here the custom results function to handle the queries...
function results($data, $form, $request)
{
$keyword = trim($request->requestVar('Search'));
$keyword = Convert::raw2sql($keyword);
$keywordHTML = htmlentities($keyword, ENT_NOQUOTES, 'UTF-8');
$pages = new ArrayList();
$news = new ArrayList();
$mode = ' IN BOOLEAN MODE';
//$mode = ' WITH QUERY EXPANSION';
//$mode = '';
$siteTreeClasses = array('Page');
$siteTreeMatch = "MATCH( Title, MenuTitle, Content, MetaTitle, MetaDescription, MetaKeywords ) AGAINST ('$keyword'$mode)
+ MATCH( Title, MenuTitle, Content, MetaTitle, MetaDescription, MetaKeywords ) AGAINST ('$keywordHTML'$mode)";
$newsItemMatch = "MATCH( Name, Content ) AGAINST ('$keyword'$mode)
+ MATCH( Name, Content ) AGAINST ('$keywordHTML'$mode)";
//Standard pages
foreach ( $siteTreeClasses as $c )
{
$query = DataList::create($c)
->where($siteTreeMatch);
$query = $query->dataQuery()->query();
$query->addSelect(array('Relevance' => $siteTreeMatch));
$records = DB::query($query->sql());
$objects = array();
foreach( $records as $record )
{
if ( in_array($record['ClassName'], $siteTreeClasses) )
$objects[] = new $record['ClassName']($record);
}
$pages->merge($objects);
}
//news
$query = DataList::create('NewsStory')->where($newsItemMatch);
$query = $query->dataQuery()->query();
$query->addSelect(array('Relevance' => $newsItemMatch));
$records = DB::query($query->sql());
$objects = array();
foreach( $records as $record ) $objects[] = new $record['ClassName']($record);
$news->merge($objects);
//sorting results
$pages->sort(array(
'Relevance' => 'DESC',
'Title' => 'ASC'
));
$news->sort(array(
'Relevance' => 'DESC',
'Date' => 'DESC'
));
//output
$data = array(
'Pages' => $pages,
'News' => $news,
'Query' => $keyword
);
return $this->customise($data)->renderWith(array('Search','Page'));
}
I add all the Page classes I want to be searched and that extend SiteTree in the $siteTreeClasses array, and the News parts can be pretty much copied for any other DataObjectI need searchable.
I am not saying this is the best solution and this can definitely be improved on, but it works for me and this might be a good stating point.
I have adapted #colymba's solution into a silverstripe module: https://github.com/burnbright/silverstripe-pagesearch
It allows setting the pagetype in the url.
You'll need to substantially overwrite SearchForm->getResults().
It uses Database->searchEngine(), but those are tailored towards SiteTree and Page classes.
The "proper" solution is to feed the data into a search engine like Solr or Sphinx.
We have the SS3-compatible "fulltextsearch" module for this purpose:
https://github.com/silverstripe-labs/silverstripe-fulltextsearch
It's going to take some upfront setup, and is only feasible if you can either host Solr yourself, or are prepared to pay for a SaaS provider. Once you've got it running though, the possibilities are endless, its a great tool!

how to use joins in Zend_Paginator_Adapter_DbSelect()

how can i replace below mysql query to ZF Zend_Paginator_Adapter_DbSelect()
query
$sql = "SELECT ps.phone_service_id,ps.phone_service_name,ps.phone_service_Duration,ps.phone_service_type,us.user_preferences_value,ps.user_id FROM phone_service ps,user_preferences us
WHERE us.phone_service_id = ps.phone_service_id
AND us.user_preferences_name = 'is_user_package_active'
AND ps.user_id =".$user_id;
i write this one but error occur could you please replace my query to equailent Zend_Paginator_Adapter_DbSelect()
$select = $DB->select()
->from(array('ps' => 'phone_service'
'us' => 'user_preferences'),
array('ps.phone_service_id', 'ps.phone_service_name','ps.phone_service_Duration','ps.phone_service_type','us.user_preferences_value')),
->where('us.phone_service_id = ?', 'ps.phone_service_id')
->where( 'us.user_preferences_name = ?', 'is_user_package_active')
->where( 'us.user_id = ?', $user_id)
;
I guess you want something like this:
$sel = $db->select();
$sel->from(array('p' => 'phone_service'))
->join(array('u' => 'user_preferences'), 'u.phone_service_id = p.phone_service_id')
->where('u.user_preferences_name = ?', 'is_user_package_active')
->where('p.user_id = ?', $user_id);

How to Use Multiple Conditions In An Update Statement With Zend_Db And QuoteInto

Using Zend Framework, is there a way to pass multiple conditions to an update statement using the quoteInto method? I've found some references to this problem but I'm looking for a supported way without having to extend Zend_Db or without concatenation.
$db = $this->getAdapter();
$data = array('profile_value' => $form['profile_value']);
$where = $db->quoteInto('user_id = ?', $form['id'])
. $db->quoteInto(' AND profile_key = ?', $key);
$this->update($data, $where);
References
http://blog.motane.lu/2009/05/21/zend_db-quoteinto-with-multiple-arguments/
http://codeaid.net/php/multiple-parameters-in-zend_db::quoteinto%28%29
You can use an array type for your $where argument. The elements will be combined with the AND operator:
$where = array();
$where[] = $this->getAdapter()->quoteInto('user_id = ?', $form['id']);
$where[] = $this->getAdapter()->quoteInto('key = ?', $key);
$this->update(array('value' => $form['value']), $where);
Since 1.8 you can use:
$where = array(
'name = ?' => $name,
'surname = ?' => $surname
);
$db->update($data, $where);
Just refreshing the above answer
$data = array('value' => $form['value']);
$where = array();
$where[] = $this->getAdapter()->quoteInto('user_id = ?', $form['id']);
$where[] = $this->getAdapter()->quoteInto('key = ?', $key);
$this->update($data, $where);

Zend Framework: How to do a DB select with multiple params?

I'm just wondering what the syntax is to do a db select in Zend Framework where two values are true. Example: I want to find if a user is already a member of a group:
$userId = 1;
$groupId = 2;
$db = Zend_Db_Table::getDefaultAdapter();
$select = new Zend_Db_Select($db);
$select->from('group_members')
->where('user_id = ?', $userId); //Right here. What do I do about group_id?
$result = $select->query();
$resultSet = $result->fetchAll();
You can use multiple where clauses which will be ANDed together by default:
$select->from('group_members')
->where('user_id = ?', $userId)
->where('group_id = ?', $groupId);
Just In case someone wants to add an OR condition to a select with multiple params
$select = $db->select()
->from('products',
array('product_id', 'product_name', 'price'))
->where('price < ?', $minimumPrice)
->orWhere('price > ?', $maximumPrice);
For more view the Zend Select manual Docs: zend.db.select