In CodeIgniter, I want to add values to an array from two different functions, but the values are being added to the array only inside the first function. Please tell what can be the issue?
Code:
public $ChnCat_tags = array();
function first_function() {
//some code
$ChnCat_tags[] = array(
'level' => $level,
'value' => $row_vct->id_vct,
'label' => $row_vct->displayname_vct,
'disable' => $disb
);
$recursion_result = second_function($ChnCat_tags);
return $ChnCat_tags; //only returns values added inside first_function
}
function second_function($ChnCat_tags) {
//some code
$ChnCat_tags[] = array(
'level' => $level,
'value' => $row_vct->id_vct,
'label' => $row_vct->displayname_vct,
'disable' => $disb
);
recursion_result = second_function($ChnCat_tags);
return recursion_result;
}
Well you could just start using $this->ChnCat_tags instead of just ChnCat_tags everywhere.
Or (pass by reference):
function first_function() {
//some code
$ChnCat_tags[] = array(
'level' => $level,
'value' => $row_vct->id_vct,
'label' => $row_vct->displayname_vct,
'disable' => $disb
);
second_function($ChnCat_tags);
return $ChnCat_tags;
}
function second_function(&$ChnCat_tags) {
//some code
$ChnCat_tags[] = array(
'level' => $level,
'value' => $row_vct->id_vct,
'label' => $row_vct->displayname_vct,
'disable' => $disb
);
second_function($ChnCat_tags);
// no need to return now
//return recursion_result;
}
do like this
function first_function() {
$ChnCat_tags[] = array(
'level' => $level,
'value' => $row_vct->id_vct,
'label' => $row_vct->displayname_vct,
'disable' => $disb
);
# Must call function with $this
$recursion_result = $this->second_function($ChnCat_tags);
# print the value of $recursion_result whish hold entire data
print_r($recursion_result);
}
function second_function($ChnCat_tags) {
$ChnCat_tags[] = array(
'level' => $level,
'value' => $row_vct->id_vct,
'label' => $row_vct->displayname_vct,
'disable' => $disb
);
# just return the array data.
return $ChnCat_tags;
}
Related
I'm using #wordpress/server-side-render to get the content of the Gutenberg block from the backend side.
if ( props && props.attributes ) {
blockContent = <ServerSideRender
block="test/employee-block"
attributes={ props.attributes }
/>
}
and here is the PHP side of the block
register_block_type( 'test/employee-block', array(
'title' => 'Test Block',
'description' => 'test',
'category' => 'widgets',
'icon' => 'admin-users',
'api_version' => 2,
'editor_script' => 'employees_dynamic_block_script',
'render_callback' => function ($block_attributes, $content) {
return '<h1>test</h1>';
}
) );
However, the $block_attributes of the render callback function is always empty. I don't know why but according to the API documentation, it should be there.
Found the fix, if you do not define the argument key and type in the register_block_type function, it does not pass them to the render callback.
register_block_type( 'test/employee-block', array(
'api_version' => 2,
'editor_script' => 'employees_dynamic_block_script',
'attributes' => array(
'selectControl' => array(
'type' => 'string',
'default' => '0',
)
),
'render_callback' => function ($block_attributes, $content) {
return '<h1>test</h1>';
}
) );
I can't figure out how to display, in my custom admin controller, 1 fields_list + content of a .tpl file. The goal is to display my product keys in stock + some extra features below (content from a tpl file).
I can display either the fields list OR the message from the .tpl file. But not combined... I found a tutorial online and this comes very close, but not working.
<?php
require_once(_PS_MODULE_DIR_ . 'avanto_key/classes/AvantoStock.php');
class AdminAvantokeyStockController extends ModuleAdminController
{
protected $position_identifier = 'id_avanto_keys';
public function __construct()
{
//$this->fields_form = $this->fieldForm();
$this->bootstrap = true;
$this->table = 'avanto_keys'; // DB table name where your object data stored
$this->className = "AvantoStock"; // The class name of my object
//$this->identifier = 'id_avanto_keys';
//$this->list_id = 'id_avanto_keys';
$this->_defaultOrderBy = 'id_avanto_keys';
//$this->lang = FALSE;
$this->addRowAction('edit');
$this->addRowAction('delete');
$this->bulk_actions = array('delete' => array('text' => $this->l('Delete selected'),
'confirm' => $this->l('Delete selected items?')), );
//Shop::addTableAssociation($this->table, array('type' => 'shop'));
parent::__construct();
$this->_select = 'pl.`name` as product_name, a.`serial_key` as serial_display';
$this->_join = 'LEFT JOIN `'._DB_PREFIX_.'product_lang` pl ON (pl.`id_product` = a.`id_product` AND pl.`id_lang`
= '.(int)$this->context->language->id.')';
}
public function renderView()
{
$tpl = $this->context->smarty->createTemplate(
dirname(__FILE__).
'/../../views/templates/admin/view.tpl');
return $tpl->fetch();
}
public function renderList()
{
$this->toolbar_title = $this->l('Stock Management');
$this->toolbar_btn['new'] = null;
$this->fields_list = array(
'id_avanto_keys' => array(
'title' => $this->l('ID Key'),
'width' => 140,
),
'id_product' => array(
'title' => $this->l('Product ID'),
'width' => 140,
),
'serial_key' => array(
'title' => $this->l('Serial Keys'),
'width' => 140,
),
'product_name' => array(
'title' => $this->l('Product Name'),
'width' => 140,
),
);
return parent::renderList();
}
public function init()
{
parent::init();
}
public function initContent()
{
$this->context->smarty->assign(array(
'form' => $form,
'base_dir' => _PS_MODULE_DIR_,
));
$this->setTemplate('stock.tpl');
$lists = parent::initContent();
$this->renderList();
$lists .= parent::initContent();
return $lists;
}
public function renderForm()
{
$this->display = 'edit';
$this->initToolbar();
$this->fields_form = array(
'tinymce' => true,
'legend' => array(
'title' => $this->l('Edit product key'),
),
'input' => array(
array(
'type' => 'text',
'label' => $this->l('Key ID'),
'name' => 'id_product',
),
array(
'type' => 'text',
'label' => $this->l('Product ID'),
'name' => 'id_avanto_keys',
),
array(
'type' => 'text',
'label' => $this->l('Serial Key'),
'required' => true,
'name' => 'serial_key',
),
),
'submit' => array(
'title' => $this->l('Save'),
'class' => 'btn btn-default pull-right'
)
);
return parent::renderForm();
}
}
?>
The code above only displays the message hello world and not my product listing.
Anyone has an idea how to combine this?
Thanks in advance!!!
It's a little bit confused, we have to make some tidy :):
First:
The fields of the list it's better to declare in the __construct so:
public function __construct()
{
$this->module = 'YourModuleName'; // Here you have to put your module name
$this->bootstrap = true;
$this->table = 'avanto_keys'; // DB table name where your object data stored
$this->className = "AvantoStock"; // The class name of my object
//$this->identifier = 'id_avanto_keys';
//$this->list_id = 'id_avanto_keys';
$this->_defaultOrderBy = 'id_avanto_keys';
//$this->lang = FALSE;
$this->explicitSelect = true; // This if you do a select manually after
$this->addRowAction('edit');
$this->addRowAction('delete');
$this->bulk_actions = array('delete' => array('text' => $this->l('Delete selected'),
'confirm' => $this->l('Delete selected items?')), );
//Shop::addTableAssociation($this->table, array('type' => 'shop'));
$this->_select = 'pl.`name` as product_name, a.`serial_key` as serial_display';
$this->_join = 'LEFT JOIN `'._DB_PREFIX_.'product_lang` pl ON (pl.`id_product` = a.`id_product` AND pl.`id_lang`
= '.(int)$this->context->language->id.')';
$this->fields_list = array(
'id_avanto_keys' => array(
'title' => $this->l('ID Key'),
'width' => 140,
),
'id_product' => array(
'title' => $this->l('Product ID'),
'width' => 140,
),
'serial_key' => array(
'title' => $this->l('Serial Keys'),
'width' => 140,
),
'product_name' => array(
'title' => $this->l('Product Name'),
'width' => 140,
),
);
parent::__construct();
}
Second
The parent renderList method make other stuff, let's separate that from what do you want to display:
public function renderList()
{
// Here we retrieve the list (without doing any strange thing)
$list = parent::renderList();
// Assign some vars to pass to our custom tpl
$this->context->smarty->assign(
array(
'var1' => "Test",
'var2' => "Test2"
)
);
// Get the custom tpl rendered
$content = $this->context->smarty->fetch(_PS_MODULE_DIR_ . "avanto_key/views/templates/admin/avantokeystock/customcontent.tpl");
// return the list plus your content
return $list . $content;
}
Third
Leave the parent initContent as is, do not override, because he make a lot of stuffs
I guess that is a great point to start :)
Try this way and let me know ;)
I am trying to add a helper form that lets the user upload images for two languages that the user can select.
However I am stuck with the form and cannot render it in the view. Here is my controller code:
<?php
class AdminWineoHeaderImgController extends ModuleAdminController
{
public function __construct()
{
$this->bootstrap = true;
$this->lang = (!isset($this->context->cookie) ||
!is_object($this->context->cookie)) ? intval(Configuration::get('PS_LANG_DEFAULT')) : intval($this->context->cookie->id_lang);
parent::__construct();
}
public function display()
{
parent::display();
}
public function renderList()
{
$this->renderForm();
$return = $this->context->smarty->fetch(_PS_MODULE_DIR_.'wineoheaderimg/views/templates/hook/adminwineoimg.tpl');
return $return;
}
public function renderForm()
{
$fields_form = array(
'form' => array(
'legend' => array(
'title' => $this->module->l('Wineo Header Img Configuration'),
'icon' => 'icon-envelope',
),
'input' => array(
array(
'type' => 'file',
'label' => $this->module->l('Add images'),
'name' => 'enable_grades',
'id' => 'uploadwineoheaderimg',
'required' => false,
'desc' => $this->module->l('Choose images that will appear on the front page.'),
),
array(
'type' => 'select',
'label' => $this->l('Languages:'),
'name' => 'category',
'required' => true,
'options' => array(
'query' => $options = array(
array(
'id_option' => 1, // The value of the 'value' attribute of the <option> tag.
'name' => 'EN', // The value of the text content of the <option> tag.
),
array(
'id_option' => 2,
'name' => 'BG',
),
),
'id' => 'id_option',
'name' => 'name',
),
),
),
'submit' => array('title' => $this->module->l('Save')),
),
);
$helper = new HelperForm();
$helper->table = 'wineoheaderimg';
$helper->default_form_language = (int) Configuration::get('PS_LANG_DEFAULT');
$helper->allow_employee_form_lang = (int) Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG');
$helper->submit_action = 'wineo_header_img_pc_form';
$helper->currentIndex = $this->context->link->getAdminLink('AdminModules', false).'&configure='.$this->module->name.'&tab_module='.$this->module->tab.'&module_name='.$this->module->name;
$helper->token = Tools::getAdminTokenLite('AdminModules');
$helper->tpl_vars = array(
'fields_value' => array(
'wineo_header_img' => Tools::getValue('enable_grades', Configuration::get('WINEO_HEADER_IMG')),
),
'languages' => $this->context->controller->getLanguages(),
);
return $helper->generateForm(array($fields_form));
}
}
Where should I call the method renderForm()? I have tried in the admin hooks and basically everywhere I could imagine.
Any help will be appreciated!
Well you are calling renderForm() inside renderList(), (I assume you want the form to display by default when you open controller page) but you don't assign the form to template.
public function renderList()
{
$form = $this->renderForm();
// To load form inside your template
$this->context->smarty->assign('form_tpl', $form);
return $this->context->smarty->fetch(_PS_MODULE_DIR_.'wineoheaderimg/views/templates/hook/adminwineoimg.tpl');
// To return form html only
return $form;
}
So if you want the form inside your adminwineoimg.tpl
{* Some HTML *}
{$form_tpl}
{* Some HTML *}
I followed the tutorial. But I can find no way to populate a form select from a database like this:
// Blog/src/Blog/Form/BlogItemForm.php
$blogCategoryTable = new Model\BlogCategoryTable;
$this->add(new Element\Select('category_id',
array('label' => 'Category', 'value_options' => $blogCategoryTable->getFormChoices())
));
Does anyone have any ideas?
I use a function to retrieve the data and set it to the form:
From my factory:
$option_for_select = $this->model->getWhatEver();
$this->add($factory->createElement(array(
'name' => 'what_ever',
'type' => 'Zend\Form\Element\Select',
'attributes' => array(
'options' => $option_for_select,
),
'options' => array(
'label' => 'What ever:',
),
)));
From the model:
public function getWhatEver()
{
$sql = "SELECT something";
$statement = $this->adapter->query($sql);
$res = $statement->execute();
// set the first option
$rows[0] = array (
'value' => '0',
'label' => 'Top',
'selected' => TRUE,
'disabled' => FALSE
);
foreach ($res as $row) {
$rows[$row['triplet_id']] = array (
'value' => $row['col1'],
'label' => $row['col2'],
);
}
return $rows;
}
How would I print the results of a form submission on the same page as the form itself?
Relevant hook_menu:
$items['admin/content/ncbi_subsites/paths'] = array(
'title' => 'Paths',
'description' => 'Paths for a particular subsite',
'page callback' => 'ncbi_subsites_show_path_page',
'access arguments' => array( 'administer site configuration' ),
'type' => MENU_LOCAL_TASK,
);
page callback:
function ncbi_subsites_show_path_page() {
$f = drupal_get_form('_ncbi_subsites_show_paths_form');
return $f;
}
Form building function:
function _ncbi_subsites_show_paths_form() {
// bunch of code here
$form['subsite'] = array(
'#title' => t('Subsites'),
'#type' => 'select',
'#description' => 'Choose a subsite to get its paths',
'#default_value' => 'Choose a subsite',
'#options'=> $tmp,
);
$form['showthem'] = array(
'#type' => 'submit',
'#value' => 'Show paths',
'#submit' => array( 'ncbi_subsites_show_paths_submit'),
);
return $form;
}
Submit function (skipped validate function for brevity)
function ncbi_subsites_show_paths_submit( &$form, &$form_state ) {
//dpm ( $form_state );
$subsite_name = $form_state['values']['subsite'];
$subsite = new Subsite( $subsite_name ); //y own class that I use internally in this module
$paths = $subsite->normalized_paths;
// build list
$list = theme_item_list( $paths );
}
If I print that $list variable, it is exactly what I want, but I am not sure how to get it into the page with the original form page built from 'ncbi_subsites_show_path_page'. Any help is much appreciated!
The key information in the link Nikit posted is $form_state['rebuild']. Here's some info from Drupal 7 documentation that I believe applies the same for Drupal 6...
$form_state['rebuild']: Normally, after the entire
form processing is completed and
submit handlers ran, a form is
considered to be done and
drupal_redirect_form() will redirect
the user to a new page using a GET
request (so a browser refresh does not
re-submit the form). However, if
'rebuild' has been set to TRUE, then a
new copy of the form is immediately
built and sent to the browser; instead
of a redirect. This is used for
multi-step forms, such as wizards and
confirmation forms. Also, if a form
validation handler has set 'rebuild'
to TRUE and a validation error
occurred, then the form is rebuilt
prior to being returned, enabling form
elements to be altered, as appropriate
to the particular validation error.
This is a full working example of a page and a list on the same page
<?php
/*
* Implements hook_mennu()
*/
function test_menu() {
$items['test'] = array(
'title' => t('Test'),
'page callback' => 'test_search_page',
'access callback' => True,
);
return $items;
}
function test_search_page(){
$form = drupal_get_form('test_search_form');
return $form;
}
function test_search_form($form, &$form_state){
$header = array(t('id'), t('name'), t('firstname'));
$rows = Null;
$form['name'] = array(
'#type' => 'textfield',
'#title' => t('Name'),
'#required' => True,
'#default_value' => isset($_GET['name']) ? $_GET['name'] : Null
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('submit'),
);
if (isset($_GET['name'])){
$rows = get_data();
}
$form['table'] = array(
'#theme' => 'table',
'#header' => $header,
'#rows' => $rows,
'#empty' => t('Aucun résultat.')
);
$form['pager'] = array('#markup' => theme('pager'));
/*
if (isset($form_state['table'])) {
$form['table'] = $form_state['table'];
}
$form['pager'] = array('#markup' => theme('pager'));
*/
return $form;
}
function test_search_form_submit($form, &$form_state){
$form_state['redirect'] = array(
// $path
'test',
// $options
array('query' => array('name' => $form_state['values']['name'])),
// $http_response_code
302,
);
}
//$header = array(t('id'), t('name'), t('firstname'));
function get_data(){
$data = array(
0 => array(
'id' => '0',
'name' => 'pokpokpok',
'firstname' => 'pokpokpok',
),
1 => array(
'id' => '1',
'name' => 'pokpokpok',
'firstname' => 'pokpokpok',
),
2 => array(
'id' => '2',
'name' => 'pokpokpok',
'firstname' => 'pokpokpok',
),
3 => array(
'id' => '3',
'name' => 'pokpokpok',
'firstname' => 'pokpokpok',
),
4 => array(
'id' => '4',
'name' => 'pokpokpok',
'firstname' => 'pokpokpok',
),
5 => array(
'id' => '5',
'name' => 'pokpokpok',
'firstname' => 'pokpokpok',
),
6 => array(
'id' => '6',
'name' => 'pokpokpok',
'firstname' => 'pokpokpok',
),
7 => array(
'id' => '7',
'name' => 'pokpokpok',
'firstname' => 'pokpokpok',
),
8 => array(
'id' => '8',
'name' => 'pokpokpok',
'firstname' => 'pokpokpok',
),
9 => array(
'id' => '9',
'name' => 'pokpokpok',
'firstname' => 'pokpokpok',
),
10 => array(
'id' => '10',
'name' => 'pokpokpok',
'firstname' => 'pokpokpok',
),
11 => array(
'id' => '11',
'name' => 'pokpokpok',
'firstname' => 'pokpokpok',
)
);
$paging = pager_array_splice($data, 2);
return $paging;
}
/*
$header = array(t('id'), t('name'), t('firstname'));
$form_state['table'] = array(
'#theme' => 'table',
'#header' => $header,
'#rows' => $paging,
'#empty' => t('Aucun r?sultat.')
);
$form_state['rebuild'] = True;*/
function pager_array_splice($data, $limit = 9, $element = 0) {
global $pager_page_array, $pager_total, $pager_total_items;
$page = isset($_GET['page']) ? $_GET['page'] : '';
// Convert comma-separated $page to an array, used by other functions.
$pager_page_array = explode(',', $page);
// We calculate the total of pages as ceil(items / limit).
$pager_total_items[$element] = count($data);
$pager_total[$element] = ceil($pager_total_items[$element] / $limit);
$pager_page_array[$element] = max(0, min((int)$pager_page_array[$element], ((int)$pager_total[$element]) - 1));
return array_slice($data, $pager_page_array[$element] * $limit, $limit, TRUE);
}
Drupal6 node.module and dblog.module do this for admin/content/node and admin/reports/dblog by providing a page callback which includes the rendered form in its output.
modules/dblog/dblog.admin.inc
dblog_overview()
modules/node/node.admin.inc
node_admin_nodes()
In form submit, updated filter settings are stored in $_SESSION.
In the page callback it renders the results based on the filter settings stored in $_SESSION.
$_SESSION is just another global here (albeit a persistent one).
For Drupal7 I find that if you use $form_state['rebuild'], then the form variables can be best accessed from the PHP super-global variable $_POST (or $_REQUEST). However, if you use $form_state['redirect'], the solution with $_SESSION is better (instead of using $_GET or $_REQUEST).
I find this issue quite tricky even for experts. Maybe Drupal has some more easy and intuitive way that we don't know.
For Drupal 8, if you have a form implementing FormBase I found I needed to set the form to be rebuilt to allow using the form state during render of the form after a successful form submission:
public function submitForm(array &$form, FormStateInterface $form_state) {
$form_state->setRebuild(TRUE);
}
By default, the form will submit and process the form, then redirect, then build the form again and at that point you don't have the form state (unless you've passed the form state as part of a query parameter in the redirect).