Laravel 5 passing page info with array - php

I'm trying to pass data about the page state (navbar links having active class when you are in that exact page), page title. I do so with an indexed array $pageInfo, however I am getting a syntax error and doen't know where?
Also do you think this is a good method or should I use view->share() instead?
public function clases()
{
$pageInfo[] =
(
'page_title' => 'Clases',
'menu_active' => 'CLases',
'sub_menu_active' => '',
);
return view('clases.list', compact('pageInfo'));
}
public function domicilio()
{
$pageInfo[] =
(
'page_title' => 'Clases a domicilio',
'menu_active' => 'Clases',
'sub_menu_active' => 'Clases a domicilio',
);
return view('clases.domicilio', compact('pageInfo'));

I suggest you read PHP basic syntax.
Basically you want to do this:
$pageInfo =
[
'page_title' => 'Clases',
'menu_active' => 'CLases',
'sub_menu_active' => '',
];
Arrays have a syntax of [key => val, ...] in PHP, you're using () as it seems.
Also $someArray[] = someValue, will append the someValue to an existing array, in your case that would create another, unwanted level of your array.
And last, you're not ending the domicilio() function. But I'll assume you just didn't paste it in (you should add } at the end, if that's not the case).

Related

Zend framework how can i get value from view and controller when render() is used?

I have this code in layout/formsde/url.phtml:
<?php
$use_url = $this->use_url;
foreach($this->match_de as $k=>$v) {
if($this->serverUrl(true) == $k) {
$use_url = $v;
}
}
?>
I have 1000 pages with following line:
<?=$this->render("layout/formsde/url");?>
Now the problem is $this->use_url and $this->match_de is null its not getting the value from Controllers where it is assigned as below:
return new ViewModel(array(
'description' => $this->de_desc,
'use_url' => $this->layout()->use_url,
'match_de' => $this->layout()->match_de,
));
How can i pass the value to ->render() ? so that i have $this->match_de value with exact which is in controller?
You can pass array with values you need to the render
//Example
$this->render('layout/formsde/url', array(
'use_url' => $this->use_url,
'match_de' => $this->match_de));
Its possible to define variables in the template which is rendered by the view renderer Zend\View\Renderer\PhpRenderer. You can pass an second argument as array.
<?=$this->render("layout/formsde/url", array(
'description' => $this->de_desc,
'use_url' => $this->layout()->use_url,
'match_de' => $this->layout()->match_de,
));?>
More information about PhpRenderer::render() method can be found in the here.

Write php array code to file without evaluating expressions

I'm trying to write some code that will generate a php file with an array, like this.
However, in order to create a correct configuration file I need to be able to leave expressions 'as is' within the array. This is because the file will be used by many users and the expressions evaluate based on environmental variables, etc. the user has set up.
So, say we have this key/value in the array I eventually want to output to the file:
[
...
'connection' => $isFork ? $sourceArray['connection'] : config('database.default'),
...
]
When this array is eventually written out to a php file (right now using var_export and file_put_contents) I will see
'connection' => config('database.default')
become
'connection' => 'default_connection',
because the expression is evaluated. What I need is a way to prevent expressions as values in the array from being evaluated but also ensuring
'connection' => $isFork ? $sourceArray['connection']
does evaluate to
'connection' => 'my_connection'
Is there any way to do this?
EDIT: I basically want to do this but in reverse and with expressions.
If I understand you correctly, your solution is to have a string representation of your array so the statements are not evaluated. I would serialize that array and put that string into the file. Tell your peeps to unserialize it right after they receive it. Better yet, json_encode your array which is going to give you a json string. You can put that in via put_file_contents and tell your peeps to json_decode the contents. They can use it as such json_decode($content, TRUE) which will give them back the associative array.
Update
So you want to write straight up PHP. I see that you have connection stuff in your array so I am thinking it is safe to think it is some sort of a configuration file that includes connection settings etc.
// filename should have the .ini at the end
function writeConfig( $filename, $yourArray ) {
$fh = fopen($filename, "w");
// making sure its available
if (!is_resource($fh)) {
return false;
}
// start dumping you array to the file
foreach ($yourArray as $key => $value) {
fwrite($fh, sprintf("%s = %s\n", $key, $value));
}
fclose($fh); // close file
return true;
}
when you want to read it
function readConfigFile( $fileThatMadeAbove ) {
return parse_ini_file($fileThatYouMadeAbove, false, INI_SCANNER_NORMAL);
}
Since it is config info, it may be better to use the ini in php.
If you want to try plain simple solution
$fp=fopen('filename.php','w');
fwrite($fp, "$yourArray");
fclose($fp);
I honestly do not know if you can do "$yourArray" or not and I do not have a place to test it. You most likely need to do a print_r($yourArray) because it is a string that you write to a file which is why I made my recommendation above.
I am out of ideas. Good luck (:
This isn't possible using var_export. The best way I can see to do this is to create a string of the output and use file_put_contents to output this to a file.
This could be achieved by replicating the array structure, e.g.
$arr_str = "[\n";
. "\t'simple_annotations' => false,\n"
. "];";
Or by creating a helper function to use instead of var_export. Something like this:
function var_str($var, $level = 0){
if(is_array($var)) return arr_str($var, $level+1);
elseif(is_string($var)) return '\''.$var.'\'';
elseif(is_numeric($var)) return $var;
elseif(is_null($var)) return 'null';
elseif(is_bool($var)) return ($var ? 'true' : 'false');
}
function arr_str($arr, $level){
$str = "[\n";
foreach($arr as $k => $e){
$str .= str_repeat("\t", $level);
$str .= "'".$k."' => ".var_str($e, $level).",\n";
}
return $str.str_repeat("\t", $level-1).']';
}
print var_str($my_array);
After searching for a few hours I came to the conclusion the only way to take full control over what I wanted to do was to use a templating engine.
The project this is for uses Laravel so I used Blade but any engine would work (I initially tried this with Twig).
I wrote out each section of my config as if it was a regular php array and then used Blade bracketing to encompass the logic needed to find the right value for each key. If the value was not an expression I evaluated the code, and if it was I wrote the expression into a string.
I ended up with this:
//example.blade.php
[
'meta' => '{{{ $isFork ? $data['metadata']['driver'] : 'annotations' }}}',
'connection' => {{{ $isFork ? '\''.$data['connection'].'\'' : 'config("database.default")' }}},
'paths' => {{ var_export(ArrayUtil::get($data['metadata']['paths'], $data['metadata']), true) }},
'repository' => '{{{ ArrayUtil::get($data['repository'], EntityRepository::class) }}}',
'proxies' => [
'namespace' => {{{ isset($data['proxy']['namespace']) ? '\'' . $data['proxy']['namespace'] .'\'' : 'false' }}},
'path' => '{{{ ArrayUtil::get($data['proxy']['directory'], storage_path('proxies')) }}}',
'auto_generate' => {{{ ArrayUtil::get($data['proxy']['auto_generate'], env('DOCTRINE_PROXY_AUTOGENERATE', 'false')) }}}
],
'events' => [
'listeners' => [],
'subscribers' => []
],
'filters' => []
]
and the output:
[
'meta' => 'yaml',
'connection' => config('database.default'),
'paths' => array(
0 => '/proj/app/Models/mappings',
),
'repository' => 'Doctrine\ORM\EntityRepository',
'proxies' => [
'namespace' => false,
'path' => '/proj/storage/proxies',
'auto_generate' => false
],
'events' => [
'listeners' => [],
'subscribers' => []
],
'filters' => []
]
You can see that where I potentially needed to expand an array I used var_export. Other than it was pretty straight forward.

Drupal : Create variable from custom .module to custom .tpl.php

I create a custom module and I want use the complete_url of my future website in the template who used/created by my module.
I tried several ways and searched Google but I don't find a solution.
However this issue seems very simply, that became me crazy x)
So, I must create a variable in my .module and add her when I return the array in the main_socialtag_theme function. Where/How can I do that ?
My .module:
function main_socialtag_block_info(){
$block['main_socialtag']=array(
'info' => t('Main socialtag'),
'cache' => DRUPAL_NO_CACHE,
);
return $block;
}
function main_socialtag_theme(){
return array(
'main_socialtag_block' => array(
'template' => 'theme/main_socialtag_block',
'variables' => array(),
),
);
}
function main_socialtag_block_view($delta=''){
if ($delta == 'main_socialtag'){
return array(
'subject' => '',
'content' => array(
'#theme' => 'main_socialtag_block',
)
);
}
}
Thanks for help, and sorry for my bad english writing !
If you are looking for a way to add, modify and call variables. Check variable_get and variable_set.
To add or modify a variable value:
variable_set("my_variable_name", "value");
To retrieve the value:
$myVal = variable_get("my_variable_name", "");
For hook_theme Implementation, kindly check this question.

cakePHP build a select box from custom array

So we have a variety of search pages each with different search criteria, so I decided to write a component which will get parameters passed to it from the controller, collect the neccesary data and return an array which I could then set to be used within my view file to populate drop down boxes to filter the criteria.
I have managed to get everything write up to where I must use the cakePHP helper to build a dynamical select box. I am convinced that I am doing something wrong and if there is an easier way to do this and still keep it somewhat dynamic please assist where you can:
// COMPONENT METHOD:
public function filterQueries($parameters) {
// Get defaults from the user:
$criteria = $parameters["custom"];
$defaults = $parameters["defaults"];
// Validate the defaults the user may want and assign them to the return array:
if($defaults != "false") {
foreach($defaults as $key => $value) {
if(array_key_exists($value, $this->defaults)) {
$this->returnArray["defaults"][$value] = $this->defaults[$value];
}
}
}
// Get all data for the custom requested form fields:
if($criteria != false) {
foreach($criteria as $model => $arguments) {
$fields = $arguments["fields"];
$conditions = $arguments["conditions"];
$recursive = $arguments["recursive"];
if(!in_array($model,$this->uses)) {
$useModel = ClassRegistry::init($model);
} else {
$useModel = $this->$$model;
}
$array = $useModel->find("all",array("conditions" => $conditions, "fields" => $fields, "recursive" => $recursive));
$this->returnArray["custom"][$model] = $array;
}
}
return $this->returnArray;
}
The above function will get an array which breaks down either custom searches or defaults (not included above but it all works, it returns the array exactly as I would have expected it.
// The code within my action to get the content from above:
// Load the Filters component to search data:
$search = $this->Components->load("Filter");
// Tell search what you want:
$searchBoxes = array(
"defaults" => array("statuses", "survey_type"),
"custom" => array(
"User" => array(
"fields" => array("User.id","User.first_name", "User.last_name"),
"conditions" => array("User.user_group_id" => "4f847c63-1840-446e-88be-3e4d29566cf0"),
"recursive" => -1
)
)
);
$filterResults = $search->filterQueries($searchBoxes);
$this->set("filters",$filterResults);
So now I get this multi-associative array within my view file (all still fine), but I want to now build example a drop down list of the users based on the array created above, but the outcome is nothing like what I expected:
echo $this->Form->input('user_id',
array(
"type" => "select",
"options" => $filters["custom"]["User"]
)
);
The HTML output is broken and displays it like this:
<option value="last_name">Doe</option>
<option value="first_name">Jihn</option>
<optgroup label="User"> </optgroup>
<optgroup label="1"> </optgroup>
<option value="last_name">Marilyn</option>
<option value="first_name">Monroe</option>
I acknowledge that I do not have a lot of cake experience but cannot understand how to just get the results to :
<option value='USERID'>NAME</option> // Yes I know the names and surnames must be concatinated still
Any advise help or guidance on how to do it, and do it the right way, would greatly be appreciated :)
VARDUMP ON $filters['custom']['users']
array
0 =>
array
'User' =>
array
'id' => string '4f84840e-cda8-4704-8fdf-210729566cf0' (length=36)
'first_name' => string 'Name' (length=4)
'last_name' => string 'Surname' (length=11)
1 =>
array
'User' =>
array
'id' => string '4f8488cb-53e0-4f72-af73-3de229566cf0' (length=36)
'first_name' => string 'Name' (length=6)
'last_name' => string 'Surname' (length=6)
You can enhance your output by doing as follows:
1) for combining two fields of a table, you can use "virtualfields" in the model, as follows: For example if you have the user model, you can define as follows:
public $virtualFields = array(
'full_name' => 'CONCAT(first_name, " ",last_name)'
);
So now the "full_name" field will be got whenever you call the find method of the User model.
2) For getting the data from the table for a select box, you can use the find('list') method. For example for the User model if you need the id,full_name (last and first name combined using the virtual fields) of the table,it can be done as follows :
$this->User->find('list',array('fields'=>array('id','full_name'),'conditions'=>$conditions))
I hope this helps..
Well I guess what you want to do is actually create another array with formatted options.
foreach ($filters["custom"]["User"] as $arr)
{
$options[$arr['id']] = $arr['first_name'] . ' ' . $arr['last_name'];
}
then
echo $this->Form->select('user_id', $options);
I think you need something like this:
$result = Set::combine($filters["custom"]["User"],
'{n}.User.id', // this is the value of select box
array(
'{0} {1}',
'{n}.User.first_name',
'{n}.User.last_name'
) // this is the text of select box
);
pr($result);
$this->form->input('inputname', array('label' => false, 'options' => array('Select optionstype','a','b'), 'class'=>array('form-a', 'b'), 'id' => 'bacid', 'style' => 'width:280px;','value'=>$abc['model']['array_attribute']));
On cakePHP 3, I can't use "virtualFields" yet, but I can use as follows:
//In PostsController
$users = $this->Posts->Users->find('list',
['keyField' => 'id',
'valueField' => 'full_name', //Don't forget to call concatened field here
'conditions' => $conditions,
'order' => $orderBy
]);
//here the magic happens
$concat = $users->func()->concat(
['Users.first_name' => 'identifier',
' ',
'Users.last_name' => 'identifier'
]);
//selecting fields
$users->select(['id', 'full_name' => $concat]);
//sending to view
$this->set('users', $users->toArray());
I hope this helps CakePHP 3 developers

Using multiple PregReplace filters on a Zend Form element

I want to be able to add multiple PregReplace filters on a single Zend Form element.
I can add one PregReplace filter using the code below:
$word = new Zend_Form_Element_Text('word');
$word->addFilter('PregReplace', array(
'match' => '/bob/',
'replace' => 'john'
));
$this->addElement($word);
I've tried
$word = new Zend_Form_Element_Text('word');
$word->addFilter('PregReplace', array(
'match' => '/bob/',
'replace' => 'john'
));
$word->addFilter('PregReplace', array(
'match' => '/sam/',
'replace' => 'dave'
));
$this->addElement($word);
but this just meant only the second filter worked.
How do I add multiple PregReplace filters?
The problem you're facing is that the second filter will override the first one in the filters stack ($this->_filters) defined in Zend_Form_Element.
As David mentioned in the question comments, the filters stack use filter names as index ($this->_filters[$name] = $filter;) this is the reason why the second filter override the first one.
In order to resolve this problem, you can use a custom filter as follows:
$element->addFilter('callback', function($v) { return preg_replace(array('/bob/', '/sam/'),array('john', 'dave'), $v); });
This is done using an inline function(), in case you're not using PHP version 5.3 or higher, you can set your callback as follows to make it work:
$element->addFilter('callback', array('callback' => array($this, 'funcName')));
And add under your init() method in your form:
function funcName($v) {
return preg_replace(array('/bob/', '/sam/'), array('john', 'dave'), $v);
}
At last, if you want to use only the PregReplace filter, unlike Marcin's answer (the syntax is incorrect), you can still do it this way:
$element->addFilter('pregReplace', array(
array('match' => array('/bob/', '/sam/'),
'replace' => array('john', 'dave')
)));
That should do the trick ;)
Since PregReplace uses php's preg_replace function, I guess something like this would be possible (preg_replace can accepts arrays of patterns and array of corresponding replacement strings):
$word = new Zend_Form_Element_Text('word');
$word->addFilter('PregReplace', array(
'match' => array('/bob/', '/sam/'),
'replace' => array('john' , dave)
));
$this->addElement($word);
I haven't tested it though. Hope it will work.
I was unable to get the previous example to work with 'PregReplace'. I switched instead to calling it with new Zend_Filter_PregReplace(). It now works for me.
$word->addFilter(new Zend_Filter_PregReplace(array(
'match' => array('/bob/', '/sam/'),
'replace'=> array('john', 'dave'))
));
I was looking for same-response does not have a usable version
$word->addFilter(new Zend_Filter_PregReplace(new Zend_Config(array(
'match'=>array('/bob/', '/sam/'),
'replace'=>array('john', 'dave')
))));

Categories