Running subquery in zend framework 2 with if condition - zend-framework2

SELECT
t1.post_id, t1.user_id, t1.total_likes, t1.total_comments,
t2.name,
if(t3.user_id, 1, 0) as user_like
FROM `game_posts` as t1
left join users as t2 ON t1.user_id=t2.user_id
left join(
select post_id, user_id from post_likes where user_id=1
)t3
on t1.post_id=t3.post_id
where t1.game_id=1
order by t1.post_id desc
I want to execute this query in zend framework 2, here is my code but i am enable to implement the second join having subquery in it.
$adapter = $this->tableGateway->getAdapter();
$sql = new Sql($adapter);
$select = $sql->select();
// MAIN POST TABLE
$select->from(array('t1' => 'game_posts'));
// GET POST USER
$select->join(
array('t2' => 'users'),
new Expression('t1.user_id = t2.user_id'),
array(
"user_name" => "name"
),
'LEFT'
);
$select->where(array("t1.game_id"=>$gameId));
$select->order("post_date DESC");
$statement = $sql->prepareStatementForSqlObject($select);
$results = $statement->execute();
$resultSet = new ResultSet();
$resultSet->initialize($results);
$result = $resultSet->toArray();
return $result;
Basically there are 3 tables game_posts, users and post_likes table,
i am fetching all the posts which has game_id=1 with name of the user who created the post along with the current user flag if he likes the post or not.
Please help me

There is your query :
$adapter = $this->tableGateway->getAdapter();
$sql = new Sql($adapter);
$select3 = $sql->select();
$select3->columns([post_id, user_id])->from(post_likes)->where(['user_id' => 1]);
$select = $sql->select();
$select->columns(['post_id', 'user_id', 'total_likes', 'total_comments', 'user_like' => new Expression('if(t3.user_id, 1, 0)')])
->from(['t1' => 'game_posts'])
->join(['t2' => 'users'], 't1.user_id=t2.user_id', ['name'], Select::JOIN_LEFT)
->join(['t3' => $select3], 't1.post_id=t3.post_id', [], Select::JOIN_LEFT)
->where(['t1.game_id' => $gameId])
->order('post_date DESC');

Related

How to group by with Zend Db

I use zend framework 2 and I want to create this select:
SELECT
MONTH(created_at) month, COUNT(*)
FROM
requests
GROUP BY
YEAR(created_at), MONTH(created_at)
This is my function I use:
public function statPerMonth() {
$select = $this->tableGateway->getSql()->select();
$select->where(array("created_at > '2017-07-01'"));
$select->columns(array(
'month' => new \Zend\Db\Sql\Expression('MONTH(created_at)'),
'count' => new \Zend\Db\Sql\Expression('COUNT(*)')
));
//$select->group(YEAR(created_at), MONTH(created_at));
$row = $this->tableGateway->selectWith($select);
return $row;
}
How can I realize it?
Thanks for help!

Adwords API CampaignCriterionService IpBlock empty IpAddress issue

We've experienced issue with CampaignCriterionService while getting IpAddress value for IpBlock criterion.
https://developers.google.com/adwords/api/docs/reference/v201502/CampaignCriterionService.IpBlock
It is impossible to get IpAddress value. If you use it in selector - you get error [SelectorError.INVALID_FIELD_NAME # serviceSelector; trigger:'IpAddress'].
$selector = new Selector();
$selector->fields = array('Id', 'CriteriaType', 'IpAddress');
$selector->predicates[] = new Predicate('CampaignId', 'EQUALS', $campaign->google_id);
$selector->predicates[] = new Predicate('CriteriaType', 'EQUALS', 'IP_BLOCK');
$selector->paging = new Paging(0, AdWordsConstants::RECOMMENDED_PAGE_SIZE);
$page = $campaignCriterionService->get($selector);
After hours of struggle we found that you should use "KeywordText" instead of "IpAddress" to get proper value. This is not obvious at all. Hope this hint saves somebody time and efforts. Such things should be definitely in documentation. So, working code looks like following:
$selector = new Selector();
$selector->fields = array('Id', 'CriteriaType', 'KeywordText');
$selector->predicates[] = new Predicate('CampaignId', 'EQUALS', $campaign->google_id);
$selector->predicates[] = new Predicate('CriteriaType', 'EQUALS', 'IP_BLOCK');
$selector->paging = new Paging(0, AdWordsConstants::RECOMMENDED_PAGE_SIZE);
$page = $campaignCriterionService->get($selector);
If you want to use IpAddress as predicate to search by it you should use the same "KeywordText", there is an example:
$selector = new Selector();
$selector->fields = array('Id', 'CriteriaType', 'KeywordText');
$selector->predicates[] = new Predicate('CampaignId', 'EQUALS', $campaign->google_id);
$selector->predicates[] = new Predicate('CriteriaType', 'EQUALS', 'IP_BLOCK');
$selector->predicates[] = new Predicate('KeywordText', 'EQUALS', '192.168.0.1/32');
$selector->paging = new Paging(0, AdWordsConstants::RECOMMENDED_PAGE_SIZE);
$page = $campaignCriterionService->get($selector);
print_r($page);
Produces output:
CampaignCriterionPage Object
(
[entries] => Array
(
[0] => NegativeCampaignCriterion Object
(
[campaignId] => 167195728
[isNegative] => 1
[criterion] => IpBlock Object
(
[ipAddress] => 192.168.0.1/32
[id] => 23078300211
[type] => IP_BLOCK
[CriterionType] => IpBlock
[_parameterMap:Criterion:private] => Array
(
[Criterion.Type] => CriterionType
)
)
[bidModifier] =>
[forwardCompatibilityMap] =>
[CampaignCriterionType] => NegativeCampaignCriterion
[_parameterMap:CampaignCriterion:private] => Array
(
[CampaignCriterion.Type] => CampaignCriterionType
)
)
)
[totalNumEntries] => 1
[PageType] => CampaignCriterionPage
[_parameterMap:Page:private] => Array
(
[Page.Type] => PageType
)
)

How do i execute multiple queries in the same function with the same adapter in ZEND 2?

This is the content of the global.php file:
return array(
'db' => array(
'driver' => 'Mysqli',
'database' => 'web_builder',
'username' => 'root',
'password' => ''
),
'service_manager' => array(
'factories' => array(
'Zend\Db\Adapter\Adapter'
=> 'Zend\Db\Adapter\AdapterServiceFactory',
),
),
);
This is the content of my model:
namespace Application\Model;
use Zend\Db\Adapter\Adapter;
use Zend\Db\TableGateway\AbstractTableGateway;
class UsersTable extends AbstractTableGateway {
public function __construct(Adapter $adapter) {
$this->adapter = $adapter;
}
public function user_login($getData,$session_id){ // manage the user's login
$email = $getData['login_email'];
$password = $getData['login_password'];
$select = $this->adapter->query ("select count(*) as counter from users where email = '$email' and password = '".md5($password)."'");
$results = $select->execute();
if ($results->current()['counter'] == 1 ){
$select->getDataSource()->getResource()->closeCursor();
$update_user = $this->adapter->query("UPDATE users SET session_id = '".$session_id."' WHERE email = '".$email."'");
$update_session = $update_user->execute();
return 1;
}else{
return 0;
}
}
}
For some reason the update query is not working. If i commented the count query it works. I observed that i cannot execute multiple queries in the same function for some God know reason :P. I'm getting this message: Statement couldn't be produced with sql: ...... . Both query works perfectly if i executed them in phpmyadmin. Can anyone explain me why this cannot work ? I'm a little desperate :| , I spent severals hours on this
It could be a formatting / preparation issue, taking a look at the manual it suggests the following format to prepare your statement:
$adapter->query('SELECT * FROM `artist` WHERE `id` = ?', array(5));
So in your case try formatting it as so:
$select = $this->adapter->query ('select count(*) as counter from users where email = ? and password = ? ', $email , md5($password) );

How to add join columns to tablegateway in zendframework 2

I am struggling with Zend now for having the joined table columns in the sql string properly.
I have this code (which works fine):
$expression = new \Zend\Db\Sql\Expression('group = acl_groups.id');
$select = $this->tableGateway->getSql()->select();
$select->columns(array(
$select::SQL_STAR,
'group',
'id',
'status'
))->join('acl_groups', 'group = acl_groups.id');
return $this->tableGateway->selectWith($select);
But I can`t get the acl_groups columns to work.
Any attempt fails. I have read the Zend Documentation and nothing effectively worked for me.
My join table has this columns:
id
name
status
I need name to have an alias "groupname"
I tried this:
$select->columns(array(
$select::SQL_STAR,
'group',
'id',
'status',
array('acl_groups.name' => 'groupname')
)
$select->columns(array(
$select::SQL_STAR,
'group',
'id',
'status',
'acl_groups.name AS groupname'
)
But none works.
You have two ways to do this as mentioned here
Method 1
$resultSet = $tableGateway->select (function (Select $select) {
// now you have `select` object, do whatever you like
});
Method 2
$select = new Select('table_name');
$select->join(
'another_table_name',
'join condition',
array('column of another table name'),
Select::JOIN_INNER
);
$resultSet = $tableGateway->selectWith($select);

Zend-Framework 2 pagination join tables

I need to add a pagination in this code:
$select = new \Zend\Db\Sql\Select ;
$select->from('school');
$select->join('school_parent','school.school_parent_id = school_parent.school_parent_id');
$resultSet = $this->tableGateway->selectWith($select);
return $resultSet;
I tried this example, but I can't do it with the join table.
Anyone can help me?
public function fetchAll($paginated=false)
{
if($paginated) {
// create a new Select object for the table album
$select = $this->getallAlbum();
// create a new result set based on the Album entity
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new Album());
// create a new pagination adapter object
$paginatorAdapter = new DbSelect(
// our configured select object
$select,
// the adapter to run it against
$this->tableGateway->getAdapter(),
// the result set to hydrate
$resultSetPrototype
);
$paginator = new Paginator($paginatorAdapter);
return $paginator;
}
$resultSet = $this->tableGateway->select();
return $resultSet;
}
function getallAlbum(){
$sql = new Select();
$sql->from('album')->columns(array('id', 'artist', 'title'))->join('albumcategory', 'album.catId = albumcategory.catId', array('catName' => 'catName'), Select::JOIN_LEFT);
return $sql;
}
Pagination should work fine with joins. This is what I have, similar to an example you provided:
$select = new \Zend\Db\Sql\Select ;
$select->from('school');
$select->join('school_parent','school.school_parent_id = school_parent.school_parent_id');
return new \Zend\Paginator\Paginator(
new \Zend\Paginator\Adapter\DbSelect(
$select,
$this->tableGateway->getAdapter()
)
);
Please post an exact error that you are getting if the above doesn't work.
Thank you for the answer, but i tried your code, but i had this PDOException message:
SQLSTATE[42S21]: Column already exists: 1060 Duplicate column name 'school_parent_id'
I also tried, to adapat my "join tables" with the example of Rob Allen:
public function fetchAll($paginated=false)
{
if($paginated) {
// create a new Select object for the table album
$select = new \Zend\Db\Sql\Select ;
$select->from('school');
$select->join('school_parent','school.school_parent_id = school_parent.school_parent_id');
// create a new result set based on the Album entity
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new School());
// create a new pagination adapter object
$paginatorAdapter = new DbSelect(
// our configured select object
$select,
// the adapter to run it against
$this->tableGateway->getAdapter(),
// the result set to hydrate
$resultSetPrototype
);
$paginator = new Paginator($paginatorAdapter);
return $paginator;
}
$resultSet = $this->tableGateway->select();
return $resultSet;
}
But the result is the same.
// create a new Select object for the table album
$select = new \Zend\Db\Sql\Select ;
$select->from('school');
$select->join('school_parent','school.school_parent_id = school_parent.school_parent_id');
//change this like the following
// create a new Select object for the table album
$select = $this->yourFunction();
//and define yourFunction like
function youFunction(){
$sql = new Select();
$sql->from('school')->columns(array('schoolid', 'schoolname', 'anotherfield'))->join('school_parent', 'school.school_parent_id= school_parent.school_parent_id', array('schoolName' => 'schoolName'), Select::JOIN_LEFT);
return $sql;
}
Please try the join syntax
$select->from('table1')->join('table2', 'table1 = table2', array('table2.colum_to_return1', 'table2.colum_to_return2'));
Example pagination and sort Url
https://github.com/bigemployee/zf2-tutorial-paginate-sort
Try with another example pagination and sorting
### module_config.php ###
'router' => array(
'routes' => array(
'album' => array(
'type' => 'segment',
'options' => array(
'route' => '/album[/:action][/:id][/page/:page][/order_by/:order_by][/:order]',
'constraints' => array(
'action' => '(?!\bpage\b)(?!\border_by\b)[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
'page' => '[0-9]+',
'order_by' => '[a-zA-Z][a-zA-Z0-9_-]*',
'order' => 'ASC|DESC',
),
'defaults' => array(
'controller' => 'Album\Controller\Album',
'action' => 'index',
),
),
),
),
),
###### AlbumController ###
namespace Album\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Album\Model\Album;
use Album\Form\AlbumForm;
use Zend\Db\Sql\Select;
use Zend\Paginator\Paginator;
use Zend\Paginator\Adapter\Iterator as paginatorIterator;
class AlbumController extends AbstractActionController {
protected $albumTable;
public function indexAction() {
$select = new Select();
$order_by = $this->params()->fromRoute('order_by') ?
$this->params()->fromRoute('order_by') : 'id';
$order = $this->params()->fromRoute('order') ?
$this->params()->fromRoute('order') : Select::ORDER_ASCENDING;
$page = $this->params()->fromRoute('page') ? (int) $this->params()->fromRoute('page') : 1;
$albums = $this->getAlbumTable()->fetchAll($select->order($order_by . ' ' . $order));
$itemsPerPage = 10;
$albums->current();
$paginator = new Paginator(new paginatorIterator($albums));
$paginator->setCurrentPageNumber($page)
->setItemCountPerPage($itemsPerPage)
->setPageRange(7);
return new ViewModel(array(
'order_by' => $order_by,
'order' => $order,
'page' => $page,
'paginator' => $paginator,
));
}
}
Add this line to your code:
$select->columns(array(new Expression('DISTINCT school.school_parent_id')));
OR something like this:
$select->join('school_parent','school.school_parent_id = school_parent.school_parent_id', array('sp_id' => 'school_parent_id'));

Resources