I'm trying to transform the array of my query result.
First I did this query:
public function findAllTraduction()
{
return $this->createQueryBuilder('c')
->select('c.key, c.content, c.id, f.locale')
->leftJoin('c.TraductionFile', 'f')
->groupBy('c.key')
->getQuery()
->getArrayResult();
}
The result is like that:
array
0 =>
array
'key' => string 'FORMAT1'
'content' => string 'login'
'id' => int 507
'locale' => string 'en'
1 =>
array
'key' => string 'FORMAT1'
'content' => string 'connecter'
'id' => int 508
'locale' => string 'fr'
2 =>
array
'key' => string 'FORMAT2'
'content' => string 'password'
'id' => int 503
'locale' => string 'en'
3 =>
array
'key' => string 'FORMAT2'
'content' => string 'mot de passe'
'id' => int 504
'locale' => string 'fr'
What I would like to have is an array like that:
array
'FORMAT1' =>
array
'en' =>
array
'content' => string 'login'
'id' => int 507
'fr' =>
array
'content' => string 'connecter'
'id' => int 508
'FORMAT2' =>
array
'en' =>
array
'content' => string 'password'
'id' => int 503
'fr' =>
array
'content' => string 'mot de passe'
'id' => int 504
In fact, for each same 'key' (here 'FORMAT1' and 'FORMAT2', regroup by 'locale' (EN and FR)
Is it possible to do that in the query ?
I tried with GROUPBY and DISTINCT but nothing happened...
If not possible in query, may be redraw an array with loop....
thank you !
Doctrine provides a way to specify indexBy when creating the QueryBuilder in order to index the resulting array not in a sequential way but by a specific key :
createQueryBuilder($alias, $indexBy = null)
So you may want to try something like createQueryBuilder('c', 'c.key') to use c keys as array indexes
I found a solution with foreach for redraw the array ...
$catalogue = [];
foreach ($catalogues_array as $index => $val) {
$key = $val['key'];
$locale = $val['locale'];
unset($catalogues_array[$index]['key']);
unset($catalogues_array[$index]['locale']);
$catalogue[$key][$locale] = $catalogues_array[$index];
}
return $catalogue;
the result :
array (size=421)
'base_template.page_title' =>
array (size=2)
'en' =>
array (size=6)
'content' => string 'Audio Video Caption - Subtitling & Transcription of media.' (length=58)
'description' => null
'traductionControle' => boolean false
'id' => int 1
'domain' => string 'messages' (length=8)
'bundleName' => string 'app' (length=3)
'fr' =>
array (size=6)
'content' => string 'Audio Video Caption - Sous-Titrage & Transcription de médias.' (length=62)
'description' => null
'traductionControle' => boolean false
'id' => int 9
'domain' => string 'messages' (length=8)
'bundleName' => string 'app' (length=3)
'base_template.meta.keywords' =>
array (size=2)
'en' =>
array (size=6)
'content' => string 'closed captioning, subtitle, speech recognition, transcription, traduction, video, audio' (length=88)
'description' => null
'traductionControle' => boolean false
'id' => int 2
'domain' => string 'messages' (length=8)
'bundleName' => string 'app' (length=3)
'fr' =>
array (size=6)
'content' => string 'sous-titre, reconnaissance vocale, transcription, traduction, video, audio' (length=74)
'description' => null
'traductionControle' => boolean false
'id' => int 10
'domain' => string 'messages' (length=8)
'bundleName' => string 'app' (length=3)
Related
I saved the information inside the database by Select-Option as serialized data.
this is my data in db :
a:2:{i:0;s:7:"#00CC6A";i:1;s:7:"#8E8CD8";}
when i want get posts with this query :
$the_query = new WP_Query(array(
'post_type' => 'product',
'showposts' => 5,
'meta_query' => array(
array(
'key' => '_my_color',
'value' => '#8E8CD8',
'compare' => 'LIKE'
)
)
));
This works . and i can get the post which value_meta is #8E8CD8
when i want to get post with array value , like this :
$the_query = new WP_Query(array(
'post_type' => 'product',
'showposts' => 5,
'meta_query' => array(
array(
'key' => '_my_color',
'value' => array('#8E8CD8','#00CC6A'),
'compare' => 'IN'
)
)
));
It doesn 't works .
i tried everything like :
serialize(array('#8E8CD8','#00CC6A'))
and this :
'relation' => 'OR',
array(
'key' => '_my_color',
'value' => '#8E8CD8',
'compare' => 'LIKE',
),
array(
'key' => '_my_color',
'value' => '#00CC6A',
'compare' => 'LIKE',
),array(
'key' => '_my_price_wd',
'value' => '585000',
'compare' => 'LIKE'
)
but i want AND result with _my_color_ and _my_price_wd_
i can't get relation with OR
I am using trntv filekit in yii2, when I update profile the widget save profile image correctly in storage but save wrong base_url in database? var_dump result show following code :
C:\wamp64\www\realestate\frontend\modules\user\controllers\DefaultController.php:72:
array (size=6)
'path' => string '1/8fxqQhjo7lhtCkMnNDM6mdo2sODCUtVb.png' (length=38)
'name' => string 'Capture' (length=7)
'size' => string '33507' (length=5)
'type' => string 'image/png' (length=9)
'order' => string '' (length=0)
'base_url' => string '/source' (length=7
but I want to get following
base_url' => string 'http://localhost/realestate/storage/web/source' (length=45)
How can I change base_url?
'fileStorage'=>[
'class' => 'trntv\filekit\Storage',
'baseUrl' => '#web/image' // you should assign this way
'filesystem'=> ...
// OR
'filesystemComponent' => ...
],
https://github.com/trntv/yii2-file-kit#file-storage
I would like to add a "virtual" field to a Prestashop 1.6 custom table in the back office. The field indice_calculo_pvp2 should not be saved into the database, as it is a calculated from the values of indice_calculo_pvp and precio_venta_recomendado. What would be the correct way to implement this?
My code is as follows :
public function renderList() {
$this->addRowAction('edit');
$this->addRowAction('delete');
$this->fields_list = array(
'id_product_price' => array(
'search' => false,
'title' => 'ID'
),
'precio_coste' => array(
'title' => 'Precio coste',
'search' => false,
'callback' => 'callback_format_price',
'suffix' => '€'
),
'indice_calculo_pvp' => array(
'title' => 'Indice de cálculo PVP',
'search' => false,
'callback' => 'callback_format_price',
'suffix' => '%'
),
'indice_calculo_pvp2' => array(
'title' => 'Indice de cálculo PVP2',
'search' => false,
'callback' => 'callback_calculate_pvp',
'suffix' => '%'
),
'precio_venta_recomendado' => array(
'title' => 'Precio de venta recomendado con IVA',
'search' => false,
'callback' => 'callback_format_price',
'suffix' => '€'
)
);
return parent::renderList();
}
Use calculation in your SQL SELECT query for the list. I don't know what your calculation formula and your SELECT query is but example of this:
$this->_select = 'a.indice_calculo_pvp / a.precio_venta_recomendado AS indice_calculo_pvp2';
You have 2 options:
You can use a callback function as in your code:
public function callback_calculate_pvp($id, $tr)
{
return $tr['indice_calculo_pvp'] * $tr['precio_venta_recomendado'];
}
You can use a virtual column in your field list indice_calculo_pvp2 and set the value in your SQL query or in getList override function (as ProductController do with price).
Good luck.
Im working on Zend Framework 2 especially with Zend Forms. I have declared a Select dropdown box in
Form:
$selectElement = new Element\Select('selectElement');
$selectElement->setAttribute('title', 'Select a Value')
->setAttribute('id', 'id');
$data = array(
array(
//Fetching the values from database
),
);
$selectElement->setAttribute('multiple', 'multiple')
->setValueOptions($data);
$this->add($selectElement);
InputFilter:
$inputFilter->add($factory->createInput(array(
'name' => 'selectElement',
'required' => false,
'filters' => array(
array(
'name' => 'Int'
),
),
)));
I have used Zend Debug to get the values which are in the selectElement dropbox in this fashion:
$dataSelectElements = $this->getRequest()->getPost('selectElement');
\Zend\Debug\Debug::dump($dataSelectElements);
Debug Result:
array(4) {
[0] => string(2) "20"
[1] => string(2) "22"
[2] => string(2) "23"
[3] => string(2) "75"
}
Basically Im getting the id's from the selectElement form to store it in the database. Right now Im getting a notice and zend form error:
Notice Error:
Notice: Array to string conversion in ..\zendframework\zendframework\library\Zend\Filter\Int.php on line 29
And a form invalid error:
array(1) {
[0] => array(1) {
["selectElement "] => array(1) {
["explodeInvalid"] => string(35) "Invalid type given. String expected"
}
}
}
Is there a solution to over come this problem. Any help would be appreciated.
The Int filter will attempt to make an Integer out of your array of data, which is not going to work.
Previously I've used the Callback filter, which can be used to loop through the data and check if each value is an Int.
For example:
'filters' => array(
array(
'name' => 'Callback',
'options' => array(
'callback' => function($values) {
return array_filter($values, function($value) {
return ((int)$value == $value);
});
}
)
),
),
I did bit differently, something like this
form
class Companyform extends Form
{
public function __construct()
{
// we want to ignore the name passed
parent::__construct('company');
$this->setAttribute ('method', 'post');
$this->setAttribute ('class', 'form-horizontal');
$this->add ( array (
'name' => 'parentID',
'type' => 'Zend\Form\Element\Select',
'attributes' => array(
'id' => 'parentID',
'type' => 'select',
'placeholder' => "Parent Company",
),
'options' => array(
'label' => 'Parent Company'
)
));
$this->add(array(
'name' => 'btnsubmit',
'attributes' => array(
'id' => 'btnsubmit',
'type' => 'submit',
'value' => 'Add',
'class' => 'btn btn-primary'
),
));
}
}
controller
public function addAction()
{
$request = $this->getRequest();
$companyList = $this->_getCompanyList();
$form = new Companyform();
$form->get('parentID')->setAttribute('options',$companyList);
if ($request->isPost())
{
$company = new Company();
$form->setInputFilter($company->getInputFilter());
$form->setData($request->getPost());
if ($form->isvalid())
{
}
}
}
public function _getCompanyList()
{
$companies = $this->Em()->getEntityManager()->getRepository('XXXX\Entity\Company')->findBy(array('isDeleted'=>'0'));
$companyIDList = array();
$companyIDList[0] = "No Parent";
foreach ($companies as $company)
{
$companyIDList[$company->id] = $company->companyName;
}
return $companyIDList;
}
Entity class
protected $inputFilter;
public function setInputFilter(InputFilterInterface $inputFilter)
{
throw new \Exception("Not used");
}
public function getInputFilter()
{
if (!$this->inputFilter) {
$inputFilter = new InputFilter();
$factory = new InputFactory();
$inputFilter->add($factory->createInput(array(
'name' => 'companyName',
'required' => true,
'filters' => array(
array('name' => 'StripTags'),
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'StringLength',
'options' => array(
'encoding' => 'UTF-8',
'min' => 2,
'max' => 255,
),
),
),
)));
$this->inputFilter = $inputFilter;
}
return $this->inputFilter;
}
You may need to add following library in entity
use Zend\InputFilter\InputFilter;
use Zend\InputFilter\Factory as InputFactory;
use Zend\InputFilter\InputFilterAwareInterface;
use Zend\InputFilter\InputFilterInterface;
In ZendFramework 2, when you creating a (add) element from your Form file, Check the attribute: inarrayvalidator is true.
$this->add(array(
'name' => 'select_name',
'type' => 'select',
'id' => 'select_name',
'options' => array(
'label' => 'Select Name',
),
'attributes' => array(
'id' => 'select_id',
'inarrayvalidator' => true,
),
));
I hope, this works...
What I am trying to do is create a selectlist using the form API, where a user can select rows and press a delete button that deletes the selected rows from the database and reloads the table with a conformation that those selected had been deleted. With my current code, when I hit the delete button I get this error:
Warning: Invalid argument supplied for foreach() in form_execute_handlers() (line 1431 of C:\xampp\htdocs\amaware\includes\form.inc).
Here is the code:
/**
* Implements hook_menu().
*/
function smsfeed_menu() {
$items = array();
$items['admin/config/content/smsfeed'] = array(
'title' => 'SMS Messages and Newsletters',
'description' => 'Edit the Setting for the SMS Feed and Newsletter',
'page callback' => 'drupal_get_form',
'page arguments' => array('smsfeed_form'),
'access arguments' => array('access administration pages'),
'type' => MENU_NORMAL_ITEM,
);
$items['admin/config/content/smsfeed/settings'] = array(
'title' => 'Settings',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => 1,
);
$items['admin/config/content/smsfeed/newsletter'] = array(
'title' => 'Newsletter',
'page callback' => 'drupal_get_form',
'page arguments' => array('newsletter_table_form'),
'access arguments' => array('access administration pages'),
'type' => MENU_LOCAL_TASK,
'weigth' => 2,
);
$items['admin/config/content/smsfeed/feed'] = array(
'title' => 'SMS Feed',
'page callback' => 'drupal_get_form',
'page arguments' => array('feed_form'),
'access arguments' => array('access administration pages'),
'type' => MENU_LOCAL_TASK,
'weight' => 3,
);
$items['admin/config/content/smsfeed/questions'] = array(
'title' => 'Questions',
'page callback' => 'drupal_get_form',
'page arguments' => array('questions_form'),
'access arguments' => array('access administration pages'),
'type' => MENU_LOCAL_TASK,
'weigth' => 4,
);
return $items;
}
/**
* Page callback: SMS Settings
*
* #see smsfeed_menu()
*/
function smsfeed_form($form, &$form_state) {
$form['response_time'] = array(
'#type' => 'textfield',
'#title' => t('Response Time (In Days)'),
'#default_value' => variable_get('response_time', 3),
'#size' => 2,
'#maxlength' => 2,
'#description' => t('The response time, in days, that users should expect.'),
);
$form['feed_keyword'] = array(
'#type' => 'textfield',
'#title' => t('Feed Keyword'),
'#default_value' => variable_get('feed_keyword', 'FEED'),
'#size' => 10,
'#maxlength' => 10,
'#description' => t('The keyword users should text to have their message moderated and added to the website feed.'),
);
$form['join_keyword'] = array(
'#type' => 'textfield',
'#title' => t('Join Keyword'),
'#default_value' => variable_get('join_keyword', 'JOIN'),
'#size' => 10,
'#maxlength' => 10,
'#description' => t('The keyword users should text to be added to the newsletter list.'),
);
$form['quit_keyword'] = array(
'#type' => 'textfield',
'#title' => t('Quite Keyword'),
'#default_value' => variable_get('quit_keyword', 'QUIT'),
'#size' => 10,
'#maxlength' => 10,
'#description' => t('The keyword users should text to be removed from the newsletter list.'),
);
return system_settings_form($form);
}
/**
* Page Callback Newsletter
*/
function newsletter_table_form($form, $form_state) {
$rows = array();
$header = array(t('User Name'), t('User Number'), t('User E-mail'),);
$query = db_select('sms_newsletter');
$query->fields('sms_newsletter', array('name', 'number', 'email',))
->orderBy('name', 'ASC');
$results = $query->execute();
foreach ($results as $line) {
$rows[] = array(
$line->name,
$line->number,
$line->email,
);
}
$form['table'] = array(
'#type' => 'tableselect',
'#header' => $header,
'#options' => $rows,
'#empty' => t('No users found'),
);
$form['delete'] = array(
'#type' => 'submit',
'#value' => t('Delect Selected'),
'#submit' => 'newsletter_table_form_delete'
);
return $form;
}
function newsletter_table_form_delete ($form, &$form_state) {
foreach ($form_state['values']['collections'] as $key => $value) {
if ($value) {
$delete = db_delete('sms_newsletter')
-> execute();
}
}
}
Any help is deeply appreciated.
EDIT:
I've edited my news_letter_table_form to read:
function newsletter_table_form_delete ($form, $form_state) {
foreach (($form_state['values']['table']) as $rows) {
//$delete = db_delete('sms_newsletter')
//-> execute();
drupal_set_message ('' . $rows . '');
//drupal_set_message ('' . $form_state['values']['table'] . '');
}
}
And the new output leaves me puzzled as to how I'd identify selected rows, and delete them from the database. Using the above newsletter_table_form_delete I get the following output:
If I select the top row nothing happens
If I select the second row the output is 1
If I select the third row the output is 2 and so on
If I select multiple rows the output is an unordered html list of the selected rows.
I'm curious now how I could take what I have now and change it so I can delete selected rows from the database.
Thanks again!
Try changing
$form['delete'] = array(
'#type' => 'submit',
'#value' => t('Delect Selected'),
'#submit' => 'newsletter_table_form_delete'
);
to
$form['delete'] = array(
'#type' => 'submit',
'#value' => t('Delect Selected'),
'#submit' => array('newsletter_table_form_delete') // <-- make this an array
);
Based on the additional info added in your question edit, I noticed that your tableselect is built without specifying array keys like:
foreach ($results as $line) {
$rows[] = array( // <-- No array keys specified here
$line->name,
$line->number,
$line->email,
);
}
Since there were no keys specified, the default by PHP is a 0-based index. That is why you are getting no results for the top row, 1 for the second row, and so on.
See the documentation for the tableselect element for an example.
I don't know what your database table structure looks like but you will probably need to query the Primary Key for the table and include it as array keys to your $rows array. That way, when you process the data in your delete function, you have the Primary Key of the row you want to delete and delete it.
For me this wasn't clear straight away so.
I would just like to add that in the end what nmc was saying is you should construct your rows like this, where you add a key to row.
foreach ($results as $line) {
$rows[$line->name] = array(
$line->name,
$line->number,
$line->email,
);