URLSegmentFilter has a static array $default_replacements which holds, among others, the string to convert ampersands to (from & to -and-) for URL's.
I'm trying to extend the class and overwrite this static to translate the ampersand convert (only value is english and).
How can I overwrite the owner static for this goal?
class URLSegmentFilterExtension extends Extension {
private static $default_replacements = array(
'/&/u' => '-and-', // I need to translate this using _t()
'/&/u' => '-and-', // And this one
'/\s|\+/u' => '-',
'/[_.]+/u' => '-',
'/[^A-Za-z0-9\-]+/u' => '',
'/[\/\?=#]+/u' => '-',
'/[\-]{2,}/u' => '-',
'/^[\-]+/u' => '',
'/[\-]+$/u' => ''
);
}
First of all: The URLSegmentFilter mainly operates in the CMS context, where you usually just have a single locale (depending on the settings of the editing Member). So using _t() alone might not be very helpful? So you'd probably have to get the current editing locale (assuming you're using Fluent or Translatable) and set the locale for translations temporarily.
I don't see a way to hook in translations via an Extension there. I think you'd be better off creating a custom subclass and use it via Injector.
Something like this should work:
<?php
class TranslatedURLSegmentFilter extends URLSegmentFilter
{
public function getReplacements()
{
$currentLocale = i18n::get_locale();
$contentLocale = Translatable::get_current_locale();
// temporarily set the locale to the content locale
i18n::set_locale($contentLocale);
$replacements = parent::getReplacements();
// merge in our custom replacements
$replacements = array_merge($replacements, array(
'/&/u' => _t('TranslatedURLSegmentFilter.UrlAnd', '-and-'),
'/&/u' => _t('TranslatedURLSegmentFilter.UrlAnd', '-and-')
));
// reset to CMS locale
i18n::set_locale($currentLocale);
return $replacements;
}
}
Then you have to enable the custom URLSegmentFilter via config by putting something like this in your mysite/_config/config.yml file:
Injector:
URLSegmentFilter:
class: TranslatedURLSegmentFilter
Update: The above example assumes you're using the Translatable module. If you're using Fluent, replace the following line:
$contentLocale = Translatable::get_current_locale();
with:
$contentLocale = Fluent::current_locale();
You can update configuration dynamically in mysite/_config.php
$defaultReplacements = Config::inst()->get('URLSegmentFilter', 'default_replacements');
$translatedAnd = _t('URLSegmentFilter.And','-and-');
$defaultReplacements['/&/u'] = $translatedAnd;
$defaultReplacements['/&/u'] = $translatedAnd;
Config::inst()->Update('URLSegmentFilter', 'default_replacements', $defaultReplacements);
I need to create classes based on the parameter passed to a function. I do it this way:
public function index($source)
{
if(in_array($source, ModuleManager::getAllModules()))
{
$provider = new $source();
if($image)
{
return $provider->getAll(true);
}
else
{
return $provider->getAll(false);
}
}
}
Notice that on line 5 I'm trying to create an object of class $source which will definitely be available. I understand that the above code is actually an eval call. I'm using Laravel 5.2 and the above code returns:
FatalThrowableError in ProcReqController.php line 19:
Fatal error: Class 'Example' not found
In the above error Example can be any class that I made. Now if I hard code the value of $source then it works just fine.
What am I getting that error?
I believe what's happening is PHP gets confused when you try to instantiate a class whose class name is in a variable and it has to do with imports.
Solution 1
Set your $class variable to the fully qualified class name including the namespace and it should work.
In this way, new $class() should work even while including parenthesis.
Solution 2
After further testing, it seems when you instantiate a variable class, it always assumes global namespace.
With this in mind, you can use class_alias to alias each of your classes. In config/app.php, you can add each class to the aliases array.
'aliases' => [
....
'Example' => App\Example::class
]
The autoloader allows you to use classes without fully qualifying them... in the php interactive shell you'll have to manually include classes AND fully qualify them.
if you have a composer project, go to it's directory and do the following to load the Primal color classes:
set_include_path(getcwd().'/vendor/primal/color/lib/Primal/Color/');
include 'Color.php';
include 'Parser.php';
include 'RGBColor.php';
include 'HSVColor.php';
$hello = Primal\Color\Parser::parse('#666');
var_export($hello->toHSV());
/*
returns
Primal\Color\HSVColor::__set_state(array(
'hue' => 0,
'saturation' => 0,
'value' => 37.647058823529413,
'alpha' => 1,
))
*/
Remove the parentheses at the end of the instantiation call, I think.
Check out this php interactive shell session:
php > class Foo { };
php > $fooname = 'Foo';
php > $bar = new $fooname;
php > var_dump($bar);
object(Foo)#2 (0) {
}
src: https://stackoverflow.com/a/4578350/2694851
I'm introducing to Phalcon, a php framework, by following the tutorial: https://docs.phalconphp.com/en/latest/reference/tutorial-rest.html
I'm facing with this problem: I have this error in the code below
class Robots must be declared abstract or implement methods
'getConnectionService(), setForceExists() etc..'
<?php
use Phalcon\Mvc\Model;
use Phalcon\Mvc\Model\Message;
use Phalcon\Mvc\Model\Validator\Uniqueness;
use Phalcon\Mvc\Model\Validator\InclusionIn;
class Robots extends Model{
public function validation()
{
// Type must be: droid, mechanical or virtual
$this->validate(
new InclusionIn(
array(
"field" => "type",
"domain" => array(
"droid",
"mechanical",
"virtual"
)
)
)
);
// Robot name must be unique
$this->validate(
new Uniqueness(
array(
"field" => "name",
"message" => "The robot name must be unique"
)
)
);
// Year cannot be less than zero
if ($this->year < 0) {
$this->appendMessage(new Message("The year cannot be less than zero"));
}
// Check if any messages have been produced
if ($this->validationHasFailed() == true) {
return false;
}
}
}
?>
And even if I try to execute an HTTP request i get:
Cannot instantiate abstract class Robots
Any ideas?
You probably didn't set your database service properly. Make sure that:
The service name is db (I've experienced problems changing the default services names)
You have set the db service in your main $di (some might instantiate another DI container and isolate the database service there)
Always use $di->setShared(...) for registering global services
Please provide more information and will be glad to help.
I just started working with Laravel. I need to rewrite a whole system I made some years ago, using Laravel 4 as base framework. In my old system, I used to have a constant.php file with some constants declared, and a globals.php file which contained lots of array sets (for example, categories statuses, type of events, langs, etc.). By doing so, I could use something like
foreach ( $langs as $code => $domain ) {
// Some stuff
}
anywhere in my app.
My question is, how can I store that info in the so called "laravel way". I tried using some sort of object to store this info, setting this as a service and creating for it a facade:
app/libraries/Project/Constants.php
namespace PJ;
class Constants {
public static $langs = [
'es' => 'www.domain.es',
'en' => 'www.domain.us',
'uk' => 'www.domain.uk',
'br' => 'www.domain.br',
'it' => 'www.domain.it',
'de' => 'www.domain.de',
'fr' => 'www.domain.fr'
];
}
app/libraries/Project/ConstantsServiceProvider.php
namespace PJ;
use Illuminate\Support\ServiceProvider;
class ConstantsServiceProvider extends ServiceProvider {
public function register() {
$this->app->singleton('PJConstants', function() {
return new Constants;
});
}
}
app/libraries/Project/ConstantsFacade.php
namespace PJ;
use Illuminate\Support\Facades\Facade;
class ConstantsFacade extends Facade {
protected static function getFacadeAccessor() {
return 'PJConstants';
}
}
composer.json
"psr-4": {
"PJ\\": "app/libraries/Project"
},
and so I access that property as PJ\Constants::$langs.
This works, but I doubt it is the most efficient or correct way of doing it. I mean, is it the right way to "propagate" a variable by creating a whole Service Provider and facades and all such stuff? Or where should I put this data?
Thanks for any advice.
EDIT # 01
Data I want to pass to all controllers and views can be directly set in script, like in the example at the beginning of my post, but it can also be generated dynamically, from a database for example. This data could be a list of categories. I need them in all views to generate a navigation bar, but I also need them to define some routing patterns (like /category/subcategory/product), and also to parse some info in several controllers (Like get info from the category that holds X product).
My array is something like:
$categories = [
1 => ['name' => 'General', 'parent' => 0, 'description' => 'Lorem ipsum...'],
2 => ['name' => 'Nature', 'parent' => 0, 'description' => 'Lorem ipsum...'],
3 => ['name' => 'World', 'parent' => 0, 'description' => 'Lorem ipsum...'],
4 => ['name' => 'Animals', 'parent' => 2, 'description' => 'Lorem ipsum...']
]
Just as an example. Index is the id of the category, and the Value is info associated with the category.
I need this array, also, available in all Controllers and Views.
So, should I save it as a Config variable? How else could I store these data; what would be the best and semantically correct way?
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');
Note that the values you set will not persist. They are only available for the current request.
Update
The config is probably not the right place to store information generated from the database. You could just use an Eloquent Model like:
class Category extends Eloquent {
// db table 'categories' will be assumed
}
And query all categories
Category::all();
If the whole Model thing for some reason isn't working out you can start thinking about creating your own class and a facade. Or you could just create a class with all static variables and methods and then use it without the facade stuff.
For Constants
Create constants.php file in the config directory:-
define('YOUR_DEFINED_CONST', 'Your defined constant value!');
return [
'your-returned-const' => 'Your returned constant value!'
];
You can use them like:-
echo YOUR_DEFINED_CONST . '<br>';
echo config('constants.your-returned-const');
For Static Arrays
Create static_arrays.php file in the config directory:-
class StaticArray
{
public static $langs = [
'es' => 'www.domain.es',
'en' => 'www.domain.us',
'uk' => 'www.domain.uk',
'br' => 'www.domain.br',
'it' => 'www.domain.it',
'de' => 'www.domain.de',
'fr' => 'www.domain.fr'
];
}
You can use it like:-
echo StaticArray::$langs['en'];
Note: Laravel includes all config files automatically, so no need of manual include :)
Create common constants file in Laravel
app/constants.php
define('YOUR_CONSTANT_VAR', 'VALUE');
//EX
define('COLOR_TWO', 'red');
composer.json
add file location at autoload in composer.json
"autoload": {
"files": [
"app/constants.php"
]
}
Before this change can take effect, you must run the following command in Terminal to regenerate Laravel’s autoload files:
composer dump-autoload
For global constants in Laravel 5, I don't like calling Config for them. I define them in Route group like this:
// global contants for all requests
Route::group(['prefix' => ''], function() {
define('USER_ROLE_ADMIN','1');
define('USER_ROLE_ACCOUNT','2');
});
I think the best way is to use localization.
Create a new file messages.php in resources/lang/en (en because that is what is set in my config/app 'locale'=>'en')
return an array of all your values
return [
'welcome' => 'Welcome to our application'
];
to retrieve for laravel 5.3 and below
echo trans('messages.welcome');
or
echo Lang::get('messages.welcome');
for 5.4 use
echo __('messages.welcome')
laravel 5.0 localization
or
laravel 5.4 localization
Just to add to the above answer you will have to include the config class before you could start using it in Laravel 5.3
use Illuminate\Support\Facades\Config;
Atleast in Laravel 5.4, in your constructor you can create them;
public function __construct()
{
\Config::set('privileged', array('user1','user2');
\Config::set('SomeOtherConstant', 'my constant');
}
Then you can call them like this in your methods;
\Config::get('privileged');
Especially useful for static methods in the Model, etc...
Reference on Laracasts.com https://laracasts.com/discuss/channels/general-discussion/class-apphttpcontrollersconfig-not-found
Just put a file constants.php file into the config directory and define your constants in that file, that file will be auto loaded,
Tested in Laravel 6+
Create a constants class:
<?php
namespace App\Support;
class Constants {
/* UNITS */
public const UNIT_METRIC = 0;
public const UNIT_IMPERIAL = 1;
public const UNIT_DEFAULT = UNIT_METRIC;
}
Then use it in your model, controller, whatever:
<?php
namespace App\Models;
use App\Support\Constants;
class Model
{
public function units()
{
return Constants::UNIT_DEFAULT;
}
}
i wanted to know in which file we can set common code, for example i wanted to set timezone to UTC, instead of putting same code in all controllers file is there any way to put the code once and it will be reflect in all files.
You may create your file in ''components'' folder. You can see this folder in "protected" folder.
Or you can write your code in controller.php
File path: webroot/protected/components/Controller.php
Can you please try to add the codes in bootstrap.php file
If you need to set the server time you can check here.It is a simple method
Change time zone
Use application params, ie:
// config part
return array(
// ...
'params' => array(
'myParam' => 123
)
// ...
);
// Then in app use
Yii::app()->params['myParam'] // Will return 123
You can also create your own params holder as component, ie:
// config part
'components' => array(
'myConfigs' => array(
'class' => 'ext.MyConfigs'
'myParam1' => 123,
'myParam2' => 'blah'
)
)
// Component in extensions
class MyConfigs extends CComponent
{
public $myParam1;
public $myParam2 = 'defaultValue';
}
// Then in app use it:
Yii::app()->myConfigs->myParam1 // will return 123