How to have global parameters in cakephp 3? - php

I'm writing an application in cakephp 3.
I want to have global variables that can be read from everywhere, even in layouts and views.
how can I save these parameters?

you can write configuration like this in your core.php :
Configure::write('Company', [
'name' => 'Pizza, Inc.',
'slogan' => 'Pizza for your body and soul'
]);
and when you can read it like this:
Configure::read('Company.name');
Configure::read('Company.slogan');
Configure::read('Company');
if you don't like to write new parameters in core.php. you can write it in another file and load it into core.php.
further tutorials are in http://book.cakephp.org/3.0/en/development/configuration.html

Related

How show smarty template from string in yii2?

I wanna use smarty template engine in yii2.
In my project, i need load view codes from database and render them from controller.
My question is this:
Is there any way to render a view code from string and control it like common render?
i need something like below:
$this->renderAsString($templateStr, ['param1'=>$val1, 'param2'=>$val2]);
this is important for me can access variable and function like as below code in index.tpl file.
$this->render('index.tpl'['param1'=>$val1, 'param2'=>$val2]);
I read this http://www.smarty.net/docs/en/resources.string.tpl but my answer is different, i think.
There is special separate extension called yii2-smarty for rendering views with Smarty. You need to install it via Composer, then configure like this for usage:
return [
//....
'components' => [
'view' => [
'renderers' => [
'tpl' => [
'class' => 'yii\smarty\ViewRenderer',
//'cachePath' => '#runtime/Smarty/cache',
],
],
],
],
];
As for your specific problem, look at these two issues on Github:
Add ability to render view from string
View renderer from db - not implemented yet
Core developer Klimov Paul recommends to use eval, but also in Smarty dedicated function exists exactly for these kind of situations.
Example 8.4. Another {eval} example
This outputs the server name (in uppercase) and IP. The assigned
variable $str could be from a database query.
<?php
$str = 'The server name is {$smarty.server.SERVER_NAME|upper} '
.'at {$smarty.server.SERVER_ADDR}';
$smarty->assign('foo',$str);
?>
Where the template is:
{eval var=$foo}

Laravel string Localization in config files

I'm having problem using trans() function in config file, I feel it not supposed to be used that way. However I've no clue on what would be the most efficient way to translate string text in config files (files in /config folder).
Original code
<?php
return [
'daily' => 'Daily'
];
When I try to implement trans() application crashes and laravel return white page without any error messages
<?php
return [
'daily' => trans('app.daily_text')
];
The config files are one of the first stuff Laravel initialize, it means you can't use Translator nor UrlGenerator inside a config file.
I don't know what you are trying to do, but you shouldn't need to use Translator inside a config file though...
You cannot not use trans or route method inside the Laravel config file. At the time the config file is loaded, these methods are not available to run. Also, the purpose of the configuration file is used for storing pure value and we should not trigger any actions inside the configuration file.
I know sometimes you want to put things into config file with dynamic data generated from route or text from language key. In my usecase is: configure the menu structure inside the config file. On that case, you should choose the approach of: storing only the translation key and an array which include information that you can generate the URL at run time.
I put my gist here for you to look up on the approach.
You can just store the key in config file like and then use the trans function in the view to get the translations:
Config file:
<?php
return [
'foo' => 'bar'
];
Then in the view:
{{ trans(config('config.foo') }}
I don't know if this is good practice but I ended doing this in my similar situation.
Config.php:
'Foo' => array('
'route' => 'route.name',
'name' => 'translated_line', //translated in lang file ex. /en/general.php
'),
Then in the view I used:
{{ Lang::get('general.'.Config::get('foo.name'))) }}
Maybe this is too late but I posted it here anyway so that maybe someone will find it useful, like me :))
As of Laravel v5.4, you can use the __ helper function to access the translations after Laravel has booted.
Example:
config/example.php
<?php
return [
'daily' => 'Daily',
'monthly' => 'app.monthly_text',
'yearly' => 'app.yearly_text'
];
resources/lang/en/app.php
<?php
return [
'monthly_text' => 'Monthly'
];
You can access the translations like so:
<?php
// ...
$daily = config('example.daily');
$a = __($daily); // "Daily"
$monthly = config('example.monthly');
$b = __($monthly); // "Monthly"
$yearly = config('example.yearly');
$c = __($yearly); // "app.yearly_text"

Laravel - Is there a Global Variable?

I am using Laravel. I have referenced my project name in several different places in my views.
I then decided to change the name of my application! So is there a global variable I can use instead and then I only have to change the name in one place next time?
I looked through the docs but couldn't see this feature..
Of course global variables exist in Laravel as well. However just because the exist it doesn't mean you should use them.
A much more suitable approach would be to store the name in a config file.
You can use app/config/app.php and just add a row:
return array(
'name' => 'FooBar',
// existing values ...
'debug' => false,
'url' => 'http://localhost',
// etc ...
);
Or create your very own config file. For example app/config/site.php
return array(
'name' => 'FooBar'
);
And you use it like this:
Config::get('app.name');
Or
Config::get('site.name');
See the documentation for more information
You can make use of View Composers
http://laravel.com/docs/4.2/responses#view-composers

How to define a global variable in Laravel?

I use to develop with Drupal. In Drupal there are global variables such as $user or $_view, so you can use these in different modules. I wonder how can I make something like this in Laravel, after the user log in, I can use the global $user in different controller.Except using session is there any other ways to implement this one? Thank you.
For most constants used globally across the application, storing them in config files is sufficient. It is also pretty simple
Create a new file in the app/config directory. Let's call it constants.php
In there you have to return an array of config values.
return [
'langs' => [
'es' => 'www.domain.es',
'en' => 'www.domain.us'
// etc
]
];
And you can access them as follows
Config::get('constants.langs');
// or if you want a specific one
Config::get('constants.langs.en');
And you can set them as well
Config::set('foo.bar', 'test');

PHP Application URL Routing

So I'm writing a framework on which I want to base a few apps that I'm working on (the framework is there so I have an environment to work with, and a system that will let me, for example, use a single sign-on)
I want to make this framework, and the apps it has use a Resource Oriented Architecture.
Now, I want to create a URL routing class that is expandable by APP writers (and possibly also by CMS App users, but that's WAYYYY ahead in the future) and I'm trying to figure out the best way to do it by looking at how other apps do it.
I prefer to use reg ex over making my own format since it is common knowledge. I wrote a small class that I use which allows me to nest these reg ex routing tables. I use to use something similar that was implemented by inheritance but it didn't need inheritance so I rewrote it.
I do a reg ex on a key and map to my own control string. Take the below example. I visit /api/related/joe and my router class creates a new object ApiController and calls it's method relatedDocuments(array('tags' => 'joe'));
// the 12 strips the subdirectory my app is running in
$index = urldecode(substr($_SERVER["REQUEST_URI"], 12));
Route::process($index, array(
"#^api/related/(.*)$#Di" => "ApiController/relatedDocuments/tags",
"#^thread/(.*)/post$#Di" => "ThreadController/post/title",
"#^thread/(.*)/reply$#Di" => "ThreadController/reply/title",
"#^thread/(.*)$#Di" => "ThreadController/thread/title",
"#^ajax/tag/(.*)/(.*)$#Di" => "TagController/add/id/tags",
"#^ajax/reply/(.*)/post$#Di"=> "ThreadController/ajaxPost/id",
"#^ajax/reply/(.*)$#Di" => "ArticleController/newReply/id",
"#^ajax/toggle/(.*)$#Di" => "ApiController/toggle/toggle",
"#^$#Di" => "HomeController",
));
In order to keep errors down and simplicity up you can subdivide your table. This way you can put the routing table into the class that it controls. Taking the above example you can combine the three thread calls into a single one.
Route::process($index, array(
"#^api/related/(.*)$#Di" => "ApiController/relatedDocuments/tags",
"#^thread/(.*)$#Di" => "ThreadController/route/uri",
"#^ajax/tag/(.*)/(.*)$#Di" => "TagController/add/id/tags",
"#^ajax/reply/(.*)/post$#Di"=> "ThreadController/ajaxPost/id",
"#^ajax/reply/(.*)$#Di" => "ArticleController/newReply/id",
"#^ajax/toggle/(.*)$#Di" => "ApiController/toggle/toggle",
"#^$#Di" => "HomeController",
));
Then you define ThreadController::route to be like this.
function route($args) {
Route::process($args['uri'], array(
"#^(.*)/post$#Di" => "ThreadController/post/title",
"#^(.*)/reply$#Di" => "ThreadController/reply/title",
"#^(.*)$#Di" => "ThreadController/thread/title",
));
}
Also you can define whatever defaults you want for your routing string on the right. Just don't forget to document them or you will confuse people. I'm currently calling index if you don't include a function name on the right. Here is my current code. You may want to change it to handle errors how you like and or default actions.
Yet another framework? -- anyway...
The trick is with routing is to pass it all over to your routing controller.
You'd probably want to use something similar to what I've documented here:
http://www.hm2k.com/posts/friendly-urls
The second solution allows you to use URLs similar to Zend Framework.
Use a list of Regexs to match which object I should be using
For example
^/users/[\w-]+/bookmarks/(.+)/$
^/users/[\w-]+/bookmarks/$
^/users/[\w-]+/$
Pros: Nice and simple, lets me define routes directly
Cons: Would have to be ordered, not making it easy to add new things in (very error prone)
This is, afaik, how Django does it
I think a lot of frameworks use a combination of Apache's mod_rewrite and a front controller. With mod_rewrite, you can turn a URL like this: /people/get/3 into this:
index.php?controller=people&method=get&id=3. Index.php would implement your front controller which routes the page request based on the parameters given.
As you might expect, there are a lot of ways to do it.
For example, in Slim Framework , an example of the routing engine may be the folllowing (based on the pattern ${OBJECT}->${REQUEST METHOD}(${PATTERM}, ${CALLBACK}) ):
$app->get("/Home", function() {
print('Welcome to the home page');
}
$app->get('/Profile/:memberName', function($memberName) {
print( 'I\'m viewing ' . $memberName . '\'s profile.' );
}
$app->post('/ContactUs', function() {
print( 'This action will be fired only if a POST request will occure');
}
So, the initialized instance ($app) gets a method per request method (e.g. get, post, put, delete etc.) and gets a route as the first parameter and callback as the second.
The route can get tokens - which is "variable" that will change at runtime based on some data (such as member name, article id, organization location name or whatever - you know, just like in every routing controller).
Personally, I do like this way but I don't think it will be flexible enough for an advanced framework.
Since I'm working currently with ZF and Yii, I do have an example of a router I've created as part of a framework to a company I'm working for:
The route engine is based on regex (similar to #gradbot's one) but got a two-way conversation, so if a client of yours can't run mod_rewrite (in Apache) or add rewrite rules on his or her server, he or she can still use the traditional URLs with query string.
The file contains an array, each of it, each item is similar to this example:
$_FURLTEMPLATES['login'] = array(
'i' => array( // Input - how the router parse an incomming path into query string params
'pattern' => '#Members/Login/?#i',
'matches' => array( 'Application' => 'Members', 'Module' => 'Login' ),
),
'o' => array( // Output - how the router parse a query string into a route
'#Application=Members(&|&)Module=Login/?#' => 'Members/Login/'
)
);
You can also use more complex combinations, such as:
$_FURLTEMPLATES['article'] = array(
'i' => array(
'pattern' => '#CMS/Articles/([\d]+)/?#i',
'matches' => array( 'Application' => "CMS",
'Module' => 'Articles',
'Sector' => 'showArticle',
'ArticleID' => '$1' ),
),
'o' => array(
'#Application=CMS(&|&)Module=Articles(&|&)Sector=showArticle(&|&)ArticleID=([\d]+)#' => 'CMS/Articles/$4'
)
);
The bottom line, as I think, is that the possibilities are endless, it just depend on how complex you wish your framework to be and what you wish to do with it.
If it is, for example, just intended to be a web service or simple website wrapper - just go with Slim framework's style of writing - very easy and good-looking code.
However, if you wish to develop complex sites using it, I think regex is the solution.
Good luck! :)
You should check out Pux https://github.com/c9s/Pux
Here is the synopsis
<?php
require 'vendor/autoload.php'; // use PCRE patterns you need Pux\PatternCompiler class.
use Pux\Executor;
class ProductController {
public function listAction() {
return 'product list';
}
public function itemAction($id) {
return "product $id";
}
}
$mux = new Pux\Mux;
$mux->any('/product', ['ProductController','listAction']);
$mux->get('/product/:id', ['ProductController','itemAction'] , [
'require' => [ 'id' => '\d+', ],
'default' => [ 'id' => '1', ]
]);
$mux->post('/product/:id', ['ProductController','updateAction'] , [
'require' => [ 'id' => '\d+', ],
'default' => [ 'id' => '1', ]
]);
$mux->delete('/product/:id', ['ProductController','deleteAction'] , [
'require' => [ 'id' => '\d+', ],
'default' => [ 'id' => '1', ]
]);
$route = $mux->dispatch('/product/1');
Executor::execute($route);
Zend's MVC framework by default uses a structure like
/router/controller/action/key1/value1/key2/value2
where router is the router file (mapped via mod_rewrite, controller is from a controller action handler which is defined by a class that derives from Zend_Controller_Action and action references a method in the controller, named actionAction. The key/value pairs can go in any order and are available to the action method as an associative array.
I've used something similar in the past in my own code, and so far it's worked fairly well.
Try taking look at MVC pattern.
Zend Framework uses it for example, but also CakePHP, CodeIgniter, ...
Me personally don't like the MVC model, but it's most of the time implemented as "View for web" component.
The decision pretty much depends on preference...

Categories