I have problem to merge two conditions in my query
public function GetInbox($user_id , $line_number = false , $seeall = false , $limit = 0,$SearchWhere = null)
{
if(!$SearchWhere)
$SearchWhere = new Where();
if(!$seeall)
{
$UsersLineTable = new UsersLinesTable($this->adapter);
$UsersLine = $UsersLineTable->fetchAll(array('user_id = ?' => $user_id,'owner_type = ?' => '1'));
if(!$UsersLine) return false;
$SearchWhere2 = new Where();
foreach ($UsersLine as $key => $value) {
$SearchWhere2->equalTo("recipient_number",$value['line_number'])
->or
->equalTo("recipient_number",'98'.$value['line_number'])
->or;
}
$Select = new Select();
$Select->where($SearchWhere2);
$Select->where($SearchWhere);
if($limit)
$Select->limit($limit);
$Select->order("receive_date DESC");
$MessageProvidersInboxTable = new MessageProvidersInboxTable($this->adapter);
return $MessageProvidersInboxTable->fetchBySelect($Select);
}else{
$MessageProvidersInboxTable = new MessageProvidersInboxTable($this->adapter);
return $MessageProvidersInboxTable->fetchAll($SearchWhere);
}
}
$SearchWhere is a Where class,
$SearchWhere2 is second conditions
In this case
$Select->where($SearchWhere2);
$Select->where($SearchWhere);
$select just contain $SearchWhere conditions.
I want this query
Where condition1 AND (condition2)
is that important that condition2 contain conditions include OR operand.
Sincerely
Try this, it should work. Writing without looking at zend\db code:
$where = new \Zend\Db\Sql\Where;
$where->addPredicate($SearchWhere, $where::OP_AND);
$where->addPredicate($SearchWhere2, $where::OP_AND);
$select->where($where);
Basically, Where object is a subclass of Predicate. So it should work as any other predicate.
Related
Let's say I am building a search that finds all the teacher and got an input where the user can put in the search term. I tried reading the phalcon documentation but I only see things like binding parameters. I read the other thread about needing prepare statements do I need that in Phalcon as well?
And my function in the model would be something like this:
public function findTeachers($q, $userId, $isUser, $page, $limit, $sort)
{
$sql = 'SELECT id FROM tags WHERE name LIKE "%' . $q . '%"';
$result = new Resultset(null, $this,
$this->getReadConnection()->query($sql, array()));
$tagResult = $result->toArray();
$tagList = array();
foreach ($tagResult as $key => $value) {
$tagList[] = $value['id'];
....
}
}
My question is for the Phalcon framework is there any settings or formats I should code for this line $sql = 'SELECT id FROM tags WHERE name LIKE "%' . $q . '%"';
And also any general recommendation for preventing SQL Injection in PhalconPHP controllers and index would be appreciated.
For reference:
My controller:
public function searchAction()
{
$this->view->disable();
$q = $this->request->get("q");
$sort = $this->request->get("sort");
$searchUserModel = new SearchUsers();
$loginUser = $this->component->user->getSessionUser();
if (!$loginUser) {
$loginUser = new stdClass;
$loginUser->id = '';
}
$page = $this->request->get("page");
$limit = 2;
if (!$page){
$page = 1;
}
$list = $searchUserModel->findTeachers($q, $loginUser->id, ($loginUser->id)?true:false, $page, $limit, $sort);
if ($list){
$list['status'] = true;
}
echo json_encode($list);
}
My Ajax:
function(cb){
$.ajax({
url: '/search/search?q=' + mapObject.q + '&sort=<?php echo $sort;?>' + '&page=' + mapObject.page,
data:{},
success: function(res) {
//console.log(res);
var result = JSON.parse(res);
if (!result.status){
return cb(null, result.list);
}else{
return cb(null, []);
}
},
error: function(xhr, ajaxOptions, thrownError) {
cb(null, []);
}
});
with q being the user's search term.
You should bind the query parameter to avoid an SQL injection. From what I can remember Phalcon can be a bit funny with putting the '%' wildcard in the conditions value so I put them in the bind.
This would be better than just filtering the query.
$tags = Tags::find([
'conditions' => 'name LIKE :name:',
'bind' => [
'name' => "%" . $q . "%"
]
])
Phalcon\Filter is helpful when interacting with the database.
In your controller you can say, remove everything except letters and numbers from $q.
$q = $this->request->get("q");
$q = $this->filter->sanitize($q, 'alphanum');
The shortest way for requests:
$q = $this->request->get('q', 'alphanum');
how can i filter product collection so it will return the collection which does not contain bundle product whose one of children is Out of stock.
Got the solution for my question
$collection = Mage::getResourceModel('catalog/product_collection');
$bundled_items = array();
Mage::getSingleton('catalog/product_visibility')->addVisibleInCatalogFilterToCollection($collection);
foreach ($collection->getAllIds() as $proId)
{
$bundled_product=Mage::getModel('catalog/product')->load($proId);
if($bundled_product->getTypeId()=="bundle")
{
$selectionCollection = $bundled_product->getTypeInstance(true)->getSelectionsCollection(
$bundled_product->getTypeInstance(true)->getOptionsIds($bundled_product), $bundled_product
);
foreach($selectionCollection as $option)
{
$product = Mage::getModel('catalog/product')->load($option->getProductId());
$stockItem = $product->getStockItem();
if($product->stock_item->is_in_stock == 0)
{
$bundled_items[] = $proId;
}
}
}
}
if(isset($bundled_items) && !empty($bundled_items))
{
$collection->addFieldToFilter('entity_id',array( 'nin' => array_unique($bundled_items)));
}
Alternate answer
Mage::getSingleton('catalog/product_status')->addVisibleFilterToCollection($collection);
Mage::getSingleton('catalog/product_visibility')->addVisibleInCatalogFilterToCollection($collection);
$otherProductIds = $collection->getAllIds();
//get only bundle
$collection = Mage::getResourceModel('catalog/product_collection')
->addAttributeToFilter('type_id','bundle');
Mage::getSingleton('catalog/product_status')->addVisibleFilterToCollection($collection);
Mage::getSingleton('catalog/product_visibility')->addVisibleInCatalogFilterToCollection($collection);
$bundleIds = $collection->getAllIds();
//checking bundle associate product stock status
$readAdapter = Mage::getSingleton('core/resource')->getConnection('core_read');
$select = $readAdapter->select()
->from(array('css'=> Mage::getSingleton('core/resource')->getTableName('cataloginventory/stock_status')),array())
->join(
array('bs'=> Mage::getSingleton('core/resource')->getTableName('bundle/selection')),
'bs.product_id = css.product_id',
array('parent_product_id')
)
->where('bs.parent_product_id IN (?)',$bundleIds)
->where('css.stock_status = 0')
->group('bs.parent_product_id');
$excludeBundleIds = $readAdapter->fetchCol($select);//return outstock associated products parent ids
$allIds = array_merge($otherProductIds, array_diff($bundleIds,$excludeBundleIds));
$collection = Mage::getResourceModel('catalog/product_collection')
->addAttributeToFilter('entity_id',array( 'in' => $allIds))
->addMinimalPrice()
->addFinalPrice();
return $collection
Hope this will helpful
I have a table called active_plans in which there are two columns: activated_date and last_billed_at. Basically, I want to create a query that looks at these two columns like this:
select all from active_plans
where last_billed_at = null AND activated_date + 1 month = today,
or if last_billed_at + 1 month = today.
I can't seem to figure out how to do this, though.
I wound up doing something a lot different:
public function getBillToday()
{
$activePlans = $this->entityManager
->createQuery('SELECT adp FROM adp
WHERE adp.activationDate IS NOT NULL')
->getResult();
$data = array();
foreach ($activePlans as $plan) {
$recur = $plan->getPlan()->getRecurringInMonths();
$nextBillTime = strtotime('-'.$recur.' months', time());
$nextBill = date('Y-m-d', $nextBillTime);
$activationDate = $plan->getActivationDate();
$lastBilledAt = $plan->getLastBilledAt() != NULL ? $plan->getLastBilledAt()->format('Y-m-d') : 0;
if ($activationDate == $nextBill || $lastBilledAt == $nextBill) {
$data[] = $plan->getId();
}
}
return $data;
}
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)', '');
I have been having trouble adding a hidden zend form element.
when i invoke addElements the form fails and prints the following error to the page.
but only when i try and add $formContactID and $formCustomerID.
Fatal error: Call to a member function getOrder() on a non-object in /home/coder123/public_html/wms2/library/Zend/Form.php on line 3291
My code is as follows.
private function buildForm()
{
$Description = "";
$FirstName = "";
$LastName = "";
$ContactNumber = "";
$Fax = "";
$Position = "";
$Default = "";
$custAddressID = "";
$CustomerID = "";
$Email = "";
$ContactID = "";
if($this->contactDetails != null)
{
$Description = $this->contactDetails['Description'];
$CustomerID = $this->contactDetails['CustomerID'];
$FirstName = $this->contactDetails['FirstName'];
$LastName = $this->contactDetails['LastName'];
$ContactNumber = $this->contactDetails['ContactNumber'];
$Position = $this->contactDetails['Position'];
$Fax = $this->contactDetails['Fax'];
$Email = $this->contactDetails['Email'];
$Default = $this->contactDetails['Default'];
$custAddressID = $this->contactDetails['custAddressID'];
$ContactID = $this->contactDetails['custContactID'];
}
$formfirstname = new Zend_Form_Element_Text('FirstName');
$formfirstname->setValue($FirstName)->setLabel('First Name:')->setRequired();
$formlastname = new Zend_Form_Element_Text('LastName');
$formlastname->setLabel('Last Name:')->setValue($LastName)->setRequired();
$formPhone = new Zend_Form_Element_Text('ContactNumber');
$formPhone->setLabel('Phone Number:')->setValue($ContactNumber)->setRequired();
$formFax = new Zend_Form_Element_Text('FaxNumber');
$formFax->setLabel('Fax Number:')->setValue($Fax);
$FormPosition = new Zend_Form_Element_Text('Position');
$FormPosition->setLabel('Contacts Position:')->setValue($Position);
$FormDescription = new Zend_Form_Element_Text('Description');
$FormDescription->setLabel('Short Description:')->setValue($Description)->setRequired();
$formEmail = new Zend_Form_Element_Text('Email');
$formEmail->setLabel('Email Address:')->setValue($Email);
$FormDefault = new Zend_Form_Element_Checkbox('Default');
$FormDefault->setValue('Default')->setLabel('Set as defualt contact for this business:');
if($Default == 'Default')
{
$FormDefault->setChecked(true);
}
$formCustomerID = new Zend_Form_Element_Hidden('customerID');
$formCustomerID->setValue($customerID);
if($this->contactID != null)
{
$formContactID = new Zend_Form_Element_Hidden('ContactID');
$formContactID->setValue($this->contactID);
}
// FORM SELECT
$formSelectAddress = new Zend_Form_Element_Select('custAddress');
$pos = 0;
while($pos < count($this->customerAddressArray))
{
$formSelectAddress->addMultiOption($this->customerAddressArray[$pos]['custAddressID'], $this->customerAddressArray[$pos]['Description']);
$pos++;
}
$formSelectAddress->setValue(array($this->contactDetails['custAddressID']));
$formSelectAddress->setRequired()->setLabel('Default Address For this Contact:');
// END FORM SELECT
$this->setMethod('post');
$this->setName('FormCustomerEdit');
$formSubmit = new Zend_Form_Element_Submit('ContactSubmit');
$formSubmit->setLabel('Save Contact');
$this->setName('CustomerContactForm');
$this->setMethod('post');
$this->addElements(array($FormDescription, $formfirstname, $formlastname,
$FormPosition, $formPhone, $formFax, $FormDefault,
$formEmail, $formSelectAddress, $formContactID, $formCustomerID, $formSubmit));
$this->addElements(array($formSubmit));
}
Maybe you've already fixed, but just in case.
I was having the same issue and the problem was the name of certain attributes within the form. In your case you have:
if($this->contactID != null){
$formContactID = new Zend_Form_Element_Hidden('ContactID');
$formContactID->setValue($this->contactID);
}
In the moment that you have added $formContactID to the form a new internal attribute has been created for the form object, this being 'ContactID'. So now we have $this->ContactID and $this->contactID.
According to PHP standards this shouldn't be a problem because associative arrays keys and objects attribute names are case sensitive but I just wanted to use your code to illustrate the behaviour of Zend Form.
Revise the rest of the code in your form to see that you are not overriding any Zend Element. Sorry for the guess but since you didn't post all the code for the form file it's a bit more difficult to debug.
Thanks and I hope it helps.
I think the problem is on $this->addElements when $formContactID is missing because of if($this->contactID != null) rule.
You can update your code to fix the problem:
.....
$this->addElements(array($FormDescription, $formfirstname, $formlastname,
$FormPosition, $formPhone, $formFax, $FormDefault,
$formEmail, $formSelectAddress, $formCustomerID, $formSubmit));
if(isset($formContactID)) {
$this->addElements(array($formContactID));
}
......