Zend_Db_Adapter_Abstract::update() must be an array - zend-db

I am having some trouble updating a row.
My class is extending Zend_Db_Table_Abstract
Here is my code:
return $this->update(
array('data' => $data),
$this->getAdapter()->quoteInto("id = ?", $id)
) ? true : false;
The exception I keep getting is:
PHP Catchable fatal error: Argument 2 passed to Zend_Db_Adapter_Abstract::update() must be an array, string given, called in /Applications/MAMP/htdocs/app/library/Session/Handler.php on line 51 and defined in /Applications/MAMP/libraries/zend-framework/ZendFramework-1.11.3-minimal/library/Zend/Db/Adapter/Abstract.php on line 587
I tried passing it an array also but nothing happens. Any idea?!

You may use array in second argument of ->update()
example:
$this->update(
array('data' => $data),
array("id = ?" => $id),
) ? true : false;
but the string must be ok
becouse
/**
* Convert an array, string, or Zend_Db_Expr object
* into a string to put in a WHERE clause.
*
* #param mixed $where
* #return string
*/
protected function _whereExpr($where)
{
if (empty($where)) {
return $where;
}
**if (!is_array($where)) {**
$where = array($where);
}

Related

Prestashop 1.7 - City field as dropdown or autocomplete

I am using Prestashop 1.7 and I need to change the city input field.
I have a billing software that only allows me to use predefined cities. So I have created a table ps_cities with the entries (id an city name).
I know how to write a dropdown or a autocomplete script, but I do not know where to change the input type in the Prestashop files.
On the 1.6 version you have the input field in a theme file, but somehow I fail to find in the new version.
In PrestaShop 1.7.7.X I've created a module that includes some new (and cool!) hooks like showing below. I consider this one a good option because it will be easier to maintain in the next PrestaShop releases.
Some assumptions here: I created a relationship model CityAddress with two fields id_city and id_address and a City model with fields like name, id_state, id_country, also I continued using Address::city string name for compatibility.
/**
* #see /classes/form/CustomerAddressFormatter.php#L156
* #param array $param [
* #var array $fields
* ]
*/
public function hookAdditionalCustomerAddressFields($params)
{
($params['fields']['city'])->setType('hidden');
// New field
$formField = $params['fields'];
$formField = (new FormField())
->setName('id_city')
->setLabel($this->l('City'))
->setRequired(true)
->setType('select')
;
// If an address already exits, select the default city
if (Tools::getIsset('id_address')) {
$address = new Address(Tools::getValue('id_address'));
if (!empty($address->id_state)) {
$cities = City::getCitiesByIdState((int) $address->id_state);
if (!empty($cities)) {
foreach ($cities as $city) {
$formField->addAvailableValue(
$city['id_city'],
$city['name']
);
}
$id_city = CityAddress::getIdCityByIdAddress((int) $address->id);
$formField->setValue($id_city);
}
}
}
// Add the id_city field in the position of the city field
$keys = array_keys($params['fields']);
$search = 'city';
foreach ($keys as $key => $value) {
if ($value == $search) {
break;
}
}
$part1 = array_slice($params['fields'], 0, $key + 1);
$part2 = array_slice($params['fields'], $key + 1);
$part1['id_city'] = $formField;
$params['fields'] = array_merge($part1, $part2);
}
This one to validate the field:
/**
* #see /classes/form/CustomerAddressForm.php#L123
* #param array $param [
* #var CustomerAddressForm $form
* ]
*/
public function hookActionValidateCustomerAddressForm($params)
{
if (empty(Tools::getValue('id_city'))
|| empty(Tools::getValue('city'))) {
return false;
}
$form = $params['form'];
$idCityField = $form->getField('id_city');
$idCity = (int) Tools::getValue('id_city');
$cityObj = new City($idCity);
$city = pSQL(Tools::getValue('city'));
if ($cityObj->name !== $city) {
$idCityField->addError(sprintf(
$this->l('Invalid name in field id_city %s and city %s'),
$cityObj->name,
$city
));
return false;
}
return true;
}
And the submitted field:
/**
* #see /classes/form/CustomerAddressForm.php#L153
* #param array $param [
* #var Address $address
* ]
*/
public function hookActionSubmitCustomerAddressForm($params)
{
/** #var Address */
$address = $params['address'];
$address->save();
if (!Validate::isLoadedObject($address)) {
throw new PrestaShopException($this->l('Address object error while trying to save city'));
}
// If address has a previous value then update it
$cityAddress = CityAddress::getCityAddressByIdAddress((int) $address->id);
$city = City::getCityByNameAndIdState($address->city, $address->id_state);
$cityAddress->id_city = $city->id;
$cityAddress->id_address = $address->id;
$cityAddress->save();
}
It is possible if you have this line in the additionalCustomerAddressFields hook:
https://github.com/PrestaShop/PrestaShop/blob/develop/classes/form/CustomerAddressFormatter.php#L150
For previous version I included ['fields' => &$format] as a parameter.
You can find all form fields of the Front Office in your theme's /templates/_partials/form-fields.tpl file

Prestashop 1.6 l method

There is an issue with the translations, if the translation is missing prestashop is returining empty string, rather than the key.
Does anyone know the location of the 'l' method used in the controllers?
$this->l('string', 'mod'); //This will output '' if string is not translated.
I want to modify the method and make it return the key if the value is empty, but I cant find it.
I'll assume you are referring to an AdminController, since it's the only one using that function. It uses the function:
protected function l($string, $class = null, $addslashes = false, $htmlentities = true)
{
if ($class === null || $class == 'AdminTab') {
$class = substr(get_class($this), 0, -10);
} elseif (strtolower(substr($class, -10)) == 'controller') {
/* classname has changed, from AdminXXX to AdminXXXController, so we remove 10 characters and we keep same keys */
$class = substr($class, 0, -10);
}
return Translate::getAdminTranslation($string, $class, $addslashes, $htmlentities);
}
In your case it would call Translate::getAdminTranslation('string', 'mod', false, true)
In Translate::getAdminTranslation
We have:
...
$string = preg_replace("/\\\*'/", "\'", $string);
$key = md5($string);
if (isset($_LANGADM[$class.$key])) {
$str = $_LANGADM[$class.$key];
} else {
$str = Translate::getGenericAdminTranslation($string, $key, $_LANGADM);
}
...
Since it won't have the $_LANGADM[$class.$key], it will call:
$str = Translate::getGenericAdminTranslation($string, $key, $_LANGADM);
in your case $str = Translate::getGenericAdminTranslation('string', md5('string'), $_LANGADM);
In there we have:
...
if (isset($lang_array['AdminController'.$key])) {
$str = $lang_array['AdminController'.$key];
} elseif (isset($lang_array['Helper'.$key])) {
$str = $lang_array['Helper'.$key];
} elseif (isset($lang_array['AdminTab'.$key])) {
$str = $lang_array['AdminTab'.$key];
} else {
// note in 1.5, some translations has moved from AdminXX to helper/*.tpl
$str = $string;
}
return $str;
So by default if no key is found, the same string that is trying to be translated is returned. So there is no need to change the function.
On the otherhand, make sure the string it's translated to an empty string. You can also debug these functions to make sure your class is correct, and the file that is storing the corresponding translations doesn't have the empty translation for those strings.

SQLSTATE[42S22]: Column not found: 1054 Unknown column '0' in 'where clause' (SQL: select * from users where 0 = admin limit 1)

I try to make login for admin using ajax.But I run into this error.I don't know where is column 0 come from.
SQLSTATE[42S22]: Column not found: 1054 Unknown column '0' in 'where
clause' (SQL: select * from users where 0 = admin limit 1)
Here is my code
public function login()
{
$username= Input::get('username');
$password= Input::get('password');
$admin=array([
'username'=>$username,
'password'=>$password,
'level'=>1
]);
if ($this->auth->attempt($admin)) {
return "ok";
}
else {
return "fail";
}
}
Model
<?php namespace App;
use Illuminate\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
class User extends Model implements AuthenticatableContract
{
use Authenticatable;
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'users';
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = ["username","password",'level'];
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = ['password'];
public $timestamps = false;
}
The issue is your $admin array. You've mixed the two syntaxes for creating arrays and you've accidentally created an array of arrays.
You need to change your $admin array to either:
$admin = array(
'username'=>$username,
'password'=>$password,
'level'=>1
);
or:
$admin = [
'username'=>$username,
'password'=>$password,
'level'=>1
];

findall() in yii return array and i want it to return object how

i have w function called update that i want to update a specific record in database according to module id (m_id) and key (key)
here is the function
public function updateRecord($module,$key,$newData){
$id = $this->module($module);
$model = new Form;
$criteria = new CDbCriteria();
$criteria->condition = "`m_id` = 1 AND `key` = 'txt'";
// $model = Yii::app()->db->createCommand("SELECT * FROM `tbl_setting` WHERE `m_id` = 1 AND `key` = 'txt'")->query();
die(var_dump($model->findAll($criteria)));
// $model = Yii::app()->db->createCommand("SELECT * FROM `tbl_setting` WHERE `m_id` = 1 AND `key` = 'txt'")->execute();
$model->m_id = $id ;
$model->attributes = $newData;
$model->save();
//die(print_r($model['m_id']));
//if(isset($_POST['save'])){
//$model['m_id'] = $id;
//}
}
every time i try to use this function it give me error that $model is not an object so it can't execute
$model->m_id = $id ;
i check out the type of findAll() and it gives an array
i checkout all find() methods and only findByPk() that give an object
and i want to choose according to the $criteria and i don't know what to do any help ?! :)
findAll will always return an array. With objects if there are record found, or an empty array on no result. find only returns 1 record, or NULL if nothing is found:
http://www.yiiframework.com/doc/api/1.1/CActiveRecord#find-detail
Your code will be save when you do it like this:
if(!is_null($model)) {
$model->m_id = $id ;
$model->attributes = $newData;
$model->save();
} else {
echo 'No record found';
}

How do I only show fields that have values, and hide fields that do not have values?

I am trying to get this code to show only fields that have values, any fields that don't have values are not meant to be displayed. It doesnt seem to be working
Any idea what I am doing wrong?
My simple test form is here http://www.healthybrighton.co.uk/wse/node/1844
/**
* Build a table of submitted values
*
* #param $form_vals array Submitted form data
* #param $select_mapping array Map select components to their value|label chocies
* #return HTML of the themed table
*/
function _format_form_state($form_vals = array(), $select_mapping) {
$output = '';
$header = array();
$rows = array();
if (!empty($form_vals)) {
foreach ($form_vals as $component_name => $component_value) {
$rows = array_merge(
$rows,
_add_component_row(
$component_name,
$component_value,
0,
$select_mapping
)
);
}
}
$output .= theme('table', $header, $rows);
return $output;
}
/**
* Build a table of submitted values
*
* #param $select_mapping array Map select components to their value|label chocies
* #param $values array Submitted form data
* #return HTML of the themed table
*/
function _format_form_state($select_mapping, $values = array()) {
$header = array(t('First'), t('Second'), t('Third'), t('Fourth'));
$rows = array();
foreach ($values as $cname => $cval) {
$rows[] = array($cname, $cval, 0, $select_mapping);
}
return theme_table($header, $rows);
}
$select_mapping should be first argument in function.
Argument with default value should not be preceded by argument without a default value.