Laravel Restful API - How to create custom query based on multiples params - rest

I am new to Laravel. I have created a Restful API with this route : (with Laravel 5)
Route::get('api/clubs', 'Api\ClubsController#getClubs');
Calling /public/api/clubs will retrieve all clubs
$clubs = Club::all();
With the same route I am trying to filter clubs based on many params :
$filter_lat = Request::get( 'fi_lat' );
$filter_long = Request::get( 'fi_long' );
$filter_distance = Request::get( 'fi_distance' );
$filter_key_word = Request::get( 'fi_key_word' );
$filter_date = Request::get( 'fi_date' );
$filter_city_id = Request::get( 'fi_city_id' );
$filter_order_by = Request::get( 'fi_order_by' );
$filter_offset = Request::get( 'fi_offset' );
$filter_limit = Request::get( 'fi_limit' );
I want to filter my clubs based on those params, but I don't know what is the best way to build the query using Eloquent. I want to be able to run the query even if I have only 1 param. example1 : I want to filter my clubs by city and my query will looks like :
$clubs = Club::where( 'city_id', $filter_city_id )->get();
If I have more params my query will looks like :
$clubs = Club::where( condition 1 )
->where( condition 2 )
->where( condition 3 )
etc ..
->get();
How to build my query this way and put together all conditions ?
if( !empty ( $my_param ) ){
$query += where ( condition .. )
}
then run $query ..
What I don't want to do, is doing 10 "if() tests" and build 10 queries depending on params because this will be really a big code hacking and duplicated query ..
I am open to any suggestions, I want to have an object of clubs as result. Thanks!

It's quite simple, just check that each condition was passed and if it did, add a where clause.
$query = Club::newQuery();
if($my_param) {
$query->where('my_param', $my_param);
}
if($my_param2) {
$query->where('my_param2', $my_param2);
}
$clubs = $query->get();
You should check that the variable is set simply because it's good practice when dealing with user submitted data. If there are some parameters which you need to validate further, be sure to use the validation class.

You can use array inside where() . like this:
User::where(['id' => $id, 'name' => $name, 'etc' => $etc])->get();
:)...

Related

How to create a dynamic 'WHERE' SQL clause using TYPO3 Querybuilder

How can I dynamically add extra conditions to 'WHERE' clauses in TYPO3 database queries please? The new TYPO3 Version 8 docs say how to make fixed queries, but not variable ones.
In the past, I could create a SQL statement and modify it dynamically like this:
if (condition) {
$strWhere = 'some SQL';
} else {
$strWhere = 'same SQL with extra bits';
}
$dbRes = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
"*", // SELECT ...
"tableName", // FROM ...
$strWhere , // WHERE...
etc.
I can't see how to do something like this using Querybuilder. What I want to achieve is an expression that does something like this
if (condition) {
->where($queryBuilder->expr()->eq(... ))
}
else {
->where($queryBuilder->expr()->eq(... ))
->andWhere($queryBuilder->expr()->eq(... ))
}
Any hints would be much appreciated. Thanks.
Solved. My mistake was in thinking that the various parts of a Query builder statement HAVE to come together - they don't.
So this:
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_tablename');
$queryBuilder
->select('uid', 'header', 'bodytext')
->from('tt_content')
->where(
$queryBuilder->expr()->eq('bodytext', $queryBuilder->createNamedParameter('klaus')),
$queryBuilder->expr()->eq('header', $queryBuilder->createNamedParameter('a name'))
)
->execute();
can also be split into parts, such as:
switch ($scope) {
case 'limitfields':
$queryBuilder->select('uid','header','bodytext');
break;
default:
$queryBuilder->select('*');
break;
}
$queryBuilder
->from('tt_content')
->where(
$queryBuilder->expr()->eq('bodytext', $queryBuilder->createNamedParameter('klaus')),
$queryBuilder->expr()->eq('header', $queryBuilder->createNamedParameter('a name'))
)
->execute();
$queryBuilder = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Database\\ConnectionPool')->getQueryBuilderForTable('tx_igldapssoauth_config');
$expressionBuilder = $queryBuilder->expr();
$conditions = $expressionBuilder->andX();
$conditions->add(
$expressionBuilder->eq('somefield', 1)
);
$conditions->add(
$expressionBuilder->eq('someotherfield', 2)
);
$rows = $queryBuilder->select('*')
->from('tx_igldapssoauth_config')
->where(
$queryBuilder->expr()->eq('uid', 1)
)
->andWhere($conditions)
->execute()->fetchAll();

Pimcore: Retrieve Single Object List by Multiple Class Types

I currently have a controller that pulls objects from the Pimcore Objects exactly how the sample data demonstrated.
What we need to accomplish with this build, is to allow for a "Featured" category to be assigned to any NewsArticle object or EventsArticle object. We need to pull a combined list from both NewsArticle and EventsArticle objects that also have the Featured category assigned to them. We need to keep track of all the IDs returned in this list, and exclude them from the single track lists so that they aren't displayed twice on the same page.
These are our two single track lists which work as expected, limited by custom properties that live on the document.
Requirements:
Filter by featured category.
Prevent any post from being listed twice.
Able to sort by date asc or desc.
// TODO: List Featured News and Events Objects...
// $this->view->featured = $featuredList->getObjects();
// List News Objects...
$newsList = new Object\NewsArticle\Listing();
$newsList->setOrderKey( "date" );
$newsList->setOrder( "DESC" );
$newsList->setLimit( $this->document->getProperty( 'newsLimit' ) );
// TODO: Exclude any IDs in $this->view->featured
$this->view->news = $newsList->getObjects();
// List Events Objects...
$eventsList = new Object\EventsArticle\Listing();
$eventsList->setOrderKey( "date" );
$eventsList->setOrder( "DESC" );
$eventsList->setLimit( $this->document->getProperty( 'eventsLimit' ) );
// TODO: Exclude any IDs in $this->view->featured
$this->view->events = $eventsList->getObjects();
This approach will give you the featured list:
$featuredListObj = \Pimcore\Model\Object::getByPath("featured-list");
$featuredListObjId = $featuredListObj->getId();
$eventClassId = \Pimcore\Model\Object\ClassDefinition::getByName("news")->getId();
$newsClassId = \Pimcore\Model\Object\ClassDefinition::getByName("event")->getId();
$combinedListing = new Pimcore\Model\Object\Listing();
$combinedListing->setCondition("o_className IN ('event','news') AND o_id IN (
SELECT o_id FROM object_$eventClassId WHERE categories LIKE '%,$featuredListObjId,%'
UNION SELECT o_id FROM object_$newsClassId WHERE categories LIKE '%,$featuredListObjId,%'
)");
foreach ($combinedListing as $item) {
echo get_class($item) . "<br>";
}
After some toil I've figured out a way to do this. It may not be optimal, but it works and gets the job done.
The reason why I've found this way to be most effective is because setCondition will also check non-target classes for columns they might not have, causing the list to fail.
#
# Hybridized Featured Articles List
#
# Get News and Events Objects...
$hybridList = new Object\Listing();
$hybridList->setCondition( "o_className IN ( 'newsArticle', 'eventsArticle' )" );
# Get a list of IDs for News and Events that have the "featured" category...
$featuredList = array();
foreach( $hybridList->getObjects() as $obj ) {
foreach( $obj->categories as $obj_cat ) {
if( $obj_cat->o_key == 'featured' ) {
$key = strtotime( $obj->date->date );
$key .= str_pad( $obj->o_id, 8, "0", STR_PAD_LEFT );
$featuredList[ $key ] = $obj;
break;
}
}
}
# Sort and Slice the list...
if( $this->document->getProperty( 'featuredSort' ) == 'asc' ) {
ksort( $featuredList ); // Oldest First
} else {
krsort( $featuredList ); // Newest First
}
$this->view->featured = array_slice( $featuredList, 0, $this->document->getProperty( 'featuredLimit' ) );
#
# Audit the Hybridized Featured Articles List for IDs
#
$block_ids = array();
foreach( $this->view->featured as $featured ) {
$block_ids[] = (int)$featured->o_id;
}
#
# News Articles List...
#
$newsList = new Object\NewsArticle\Listing();
$newsList->setOrderKey( "date" );
$newsList->setOrder( $this->document->getProperty( 'newsSort' ) == 'asc' ? 'asc' : 'desc' );
$newsList->setCondition( 'o_id NOT IN ('.implode( ',', $block_ids ).')' );
$newsList->setLimit( $this->document->getProperty( 'newsLimit' ) );
$this->view->news = $newsList->getObjects();
#
# Events Articles List...
#
$eventsList = new Object\EventsArticle\Listing();
$eventsList->setOrderKey( "date" );
$eventsList->setOrder( $this->document->getProperty( 'eventsSort' ) == 'asc' ? 'asc' : 'desc' );
$eventsList->setCondition( 'o_id NOT IN ('.implode( ',', $block_ids ).')' );
$eventsList->setLimit( $this->document->getProperty( 'eventsLimit' ) );
$this->view->events = $eventsList->getObjects();

How do i pass a variable for the query in a get Manager call?

I am trying to make a simple Rose DB call:
$id = xyz;
$name = "company";
DataB::testTable::Manager->get_testTable( query =>[ id => $id, name => $name ] );
in it possible to not have the whole query written every time, and declare it like a string variable such that i can just call
DataB::testTable::Manager->get_testTable( query =>[ $query ] );
where $query = qq { id => $id , name => $name };
Please Help
By what I understood from your question, I am giving this answer.
Try this one.
my $myquery = {query =>{ id=>$id, name=>$name }} ;
TGI::testTable::Manager->get_testTable($myquery);
Hope, this gives some idea to you.
Edit for "Hash with Array reference":
my $myquery = [ id=>$id, name=>$name ] ;
TGI::testTable::Manager->get_testTable(query => $myquery);
check out this : How to pass a a string variable as "query" for get Manager call?
Well actually i figured out how to do that . Its not that complicated. Only thing is RoseDB objects expect an array reference for a query. So something like this works :
my #query = ( id => $id, name => $name );
testDB::testTable::Manager->get_testTable( query => \#query );
Just thought would answer it myself, incase someonelse is looking for a solution to this

How do I do this sql query in Zend?

How do I do this sql query in Zend Framework, I need to some how do this in the PDO context I think? I tried ->query but not sure if I am getting this right. The three variables are user_id and to and from date.
SELECT
ss.subcategory_id,
ss.subcategory_name,
ss.subcategory_issaving,
IFNULL(SUM(m.mv_monthly_total),0) AS expendsum
FROM
(SELECT
s.subcategory_id,
s.subcategory_name,
s.subcategory_issaving
FROM
subcategory s
WHERE
s.subcategory_isexpend = 'Y'
AND
s.subcategory_issaving = 'Y') ss
LEFT JOIN
mv_monthly m
ON ss.subcategory_id = m.mv_monthly_subcategory_id
AND m.mv_monthly_user_id = 2
AND m.mv_monthly_month >= '2010-01-01'
AND m.mv_monthly_month <= '2020-01-01'
GROUP BY
ss.subcategory_id,
ss.subcategory_name,
ss.subcategory_issaving
ORDER BY
ss.subcategory_issaving DESC,
expendsum;
I have tried the following with no luck
$db = Zend_Db_Table::getDefaultAdapter();
$dbExpr1 = new Zend_Db_Expr("s.subcategory_id, s.subcategory_name, s.subcategory_issaving");
$dbExpr2 = new Zend_Db_Expr("ss.subcategory_id, ss.subcategory_name, ss.subcategory_issaving, IFNULL(SUM(m.mv_monthly_total),0) AS expendsum");
$select = $db->select()
->from(
array(
'ss' => new Zend_Db_Expr(
'('. $db->select()
->from(array("s" => "subcategory"), $dbExpr1)
->where("s.subcategory_isexpend = 'Y'")
->where("s.subcategory_issaving = 'Y'") .')'
)
),
$dbExpr2
)
->joinLeft(array("m" => "mv_monthly"), "ss.subcategory_id = m.mv_monthly_subcategory_id")
->where("m.mv_monthly_user_id = ?", $user_id)
->where("m.mv_monthly_month >= ?", $fromMonth)
->where("m.mv_monthly_month <= ?", $toMonth)
->group(array("ss.subcategory_id","ss.subcategory_name","ss.subcategory_issaving"))
->order(array("ss.subcategory_issaving DESC", "expendsum"));
$row = $db->fetchAll($select);
For such a complex query, you can just execute it directly rather than using the object oriented approach as it gets fairly complicated with a query like that.
Try something like this, replacing my query with yours, and binding your variables into the query:
$db = Zend_Db_Table::getDefaultAdapter();
$stmt = new Zend_Db_Statement_Pdo($db, 'SELECT a, b, c FROM a WHERE username = ? AND date = ?');
try {
$res = $stmt->execute(array($user_id, $fromMonth));
if ($res) {
$rows = $stmt->fetchAll();
}
} catch (Zend_Db_Statement_Exception $dbex) {
// log Query failed with exception $dbex->getMessage();
}
If you prefer to use the object oriented approach, or need to because some parts of the query will be conditional, I usually build by subqueries up first as their own select, and you can simply embed those in to the main query with the select object for the subquery.
Here is what I mean by that:
$subselect = $this->getDbTable()
->select()
->from('mytable', array('time' => 'max(time)', 'id'))
->where('id IN (?)', $serialNumbers)
->group('id');
$select = $this->getDbTable()
->select()
->setIntegrityCheck(false)
->from('mytable')
->join('other', 'mytable.id = other.id', array('label'))
->join(array('dt' => $subselect),
'(mytable.time, mytable.id) = (dt.time, dt.id)', '');

Zend get foreign ID from login table

I am using Zend and Doctrine to login using a table containing also a foreign ID to another table. I need to get this ID in order to use it in a Doctrine query (through the controller) to the database like this:
$q = Doctrine_Query::create()
->from('Lost_Model_Item i')
->where('i.StatID = ?', 'I need the ID here')
$result = $q->fetchArray();
I have tried to get it like this:
Zend_Auth::getInstance()->getIdentity()->ID
But it seems to not work. I am new to Zend and a bit lost here. Could you please help?
As I ma working with doctrine I have created an adapter as follow:
public function authenticate()
{
$q = Doctrine_Query::create()
->from('Lost_Model_Station u')
->where('u.username = ? AND u.password = MD5(?)',
array($this->username, $this->password)
);
$result = $q->fetchArray();
if (count($result) == 1) {
$this->_resultArray = $result[0];
return new Zend_Auth_Result(
Zend_Auth_Result::SUCCESS, $this->username, array());
} else {
return new Zend_Auth_Result(
Zend_Auth_Result::FAILURE, null,
array('Authentication unsuccessful')
);
}
}
How about using getIdentity to get the username and then use a sql join on Lost_Model_Item and Lost_Model_Station
$q = Doctrine_Query::create()
->from('Lost_Model_Item i')
->leftJoin('i.Lost_Model_Station u')
->where('u.username = ?', Zend_Auth::getInstance()->getIdentity())
$result = $q->fetchArray();
This assumes that there is a doctrine "hasOne" relation defined for Lost_Model_Station (in the base class):
public function setUp()
{
parent::setUp();
$this->hasOne('Lost_Model_Item', array(
'local' => 'StatID',
'foreign' => 'whatever_id_StatID_relates_to'));
}
Zend_Auth::getInstance()->getIdentity()->ID
well you got what you store in Identity . You need to post the code where you ask user to login . Because there you are not storing the ID inside the session storage which Zend_Auth uses . Basically do this there
$row = $this->_adapter->getResultRowObject();
Zend_Auth::getInstance()->getStorage()->write($row);
where $this->_adapter is
$this->_adapter = new Zend_Auth_Adapter_DbTable();
$this->_adapter->setTableName('users')
->setIdentityColumn('email')
->setCredentialColumn('password');