Yii :: Mulitilanguage issues - yii

I am developing a project in Yii multi language and i done setting up the language files , now i need to fetch english message if any translation is missing in current language file.
my file structure is :
-> protected
-> messages
->en -> main.php
->nl -> main.php etc...

Try this
Add this in your config/main.php in components array.
'messages' => array(
'onMissingTranslation' => array('MessageHelper', 'textMissingTranslation'),
),
Create a file MessageHelper.php in components and add the below code in it
class MessageHelper
{
public static function textMissingTranslation($event)
{
$var = include( Yii::getPathOfAlias( 'application.messages.en.main').'.php' );
return $event->message = $var[$event->message];
}
}

Related

ASP.NET Core Identity as UI base URL

Identity URLs are all of the form : /Identity/Account/Login etc
How can I change them (all) to be of the form /myapp/Identity/Account/Login etc ?
Is there a single "base" property or setter ?
(using latest .NET Core 3 preview 8)
The default UI uses Razor Pages, and by convention, the URLs are based on the filesystem path, similar to how Web Forms used to work back in the day. In other words, that's the URL because the page is literally located at /Areas/Identity/Pages/Account/Login.cshtml (the Areas and Pages portions of the path are logical, and removed from the URL by convention, leaving just /Identity/Account/Login.
If you want to modify this, you'll need to specify custom routes, via something like:
services.AddMvc()
.AddRazorPagesOptions(options =>
{
options.Conventions.AddPageRoute("/Identity/Account/Login", "Login");
});
You can also change the route on the actual page via the #page directive in the cshtml file:
`#page "Login"`
However, for the Identity UI, that approach would require you to scaffold the page into your project, obviously, in order to be able to change that.
For chaning Razor Page route, you could try Use a parameter transformer to customize page routes
Detail steps below:
IdentityParameterTransformer
public class IdentityParameterTransformer : IOutboundParameterTransformer
{
public string TransformOutbound(object value)
{
if (value == null) { return null; }
// Slugify value
if (value.ToString().StartsWith("Identity"))
{
return $"/MyApp/{ value.ToString() }";
}
return value.ToString();
}
}
Register
services.AddMvc().AddRazorPagesOptions(options =>
{
options.Conventions.Add(
new PageRouteTransformerConvention(
new IdentityParameterTransformer()));
});

Voyager - laravel admin panel

My question is related to controller in Voyager admin panel. For example I created a table with migration . It's name was "groups" and then I created BREAD and added it to menu in Voyager.
I created a folder that it's name is "groups" in \resources\views\vendor\voyager andthen I created two file to override the view.
But I do not know where the controller is . I created controller with php artisan make:controller GroupsController. I guess this controller is not related to voyager controllers.
I want to change the index or create method and pass some data to views in controller but I do not know where it is.
I created a controller in \vendor\tcg\voyager\src\Http\Controllers that it's name is VoyagerGroupsController.php but when I create class and index method in it , it does not work.
How can I create controller for "groups" and pass the data to the view?
Whenever we create a table in voyager, Voyager calls it datatype. And for all tables / datatypes created by us, Voyager users only one controller VoyagerBreadController.php located at **vendor\tcg\voyager\src\Http\Controllers**.
For example, if I create a table named brands. Laravel will use controller VoyagerBreadController.
But where are the routes which use or point to this controller. Routes are located in file vendor\tcg\voyager\routes\voyager.php. In this file, find the following lines:
try {
foreach (\TCG\Voyager\Models\DataType::all() as $dataTypes) {
Route::resource($dataTypes->slug, $namespacePrefix.'VoyagerBreadController');
}
} catch (\InvalidArgumentException $e) {
throw new \InvalidArgumentException("Custom routes hasn't been configured because: ".$e->getMessage(), 1);
} catch (\Exception $e) {
// do nothing, might just be because table not yet migrated.
}
In my version, these lines are between line No. 29 to 37.
As you can see, above code is fetching all our datatypes and creating a resouce route for our tables / datatypes.
Now, if I want to override this route and create a route to use my own controller for a particular action. For example, if I want to create a route for brands/create url. I can do this by simply adding following line (my route) below above code (i.e. after line 37):
Route::get('brands/create', function(){return 'abc';})->name('brands.create');
or you can do the same by adding following line in routes\web.php after Voyager::routes();
Route::get('brands/create', function(){return 'abc';})->name(**'voyager.brands.create'**);
Because it's now it's using your App controller not a Voyager controller so you have to override your full controller
like
In config/voyager.php add
'controllers' => [
'namespace' => 'App\\Http\\Controllers',
],
Create new controller like MyBreadController.php into App/controller
<?php
namespace App\Http\Controllers;
class MyBreadController extends \TCG\Voyager\Http\Controllers\Controller
{
//code here
}
app/Providers/AppServiceProvider.php
use TCG\Voyager\Http\Controllers\VoyagerBreadController;
use App\Http\Controllers\MyBreadController;
public function register()
{
$this->app->bind(VoyagerBreadController::class, MyBreadController::class);
//
}
I added Route::get('groups', 'GroupsController#index') as you said in routes/web.php
like this
Route::group(['prefix' => 'admin'], function () {
Voyager::routes();
Route::get('groups', 'GroupsController#index');
});
and added these lines in index method
public function index(Request $request){
// GET THE SLUG, ex. 'posts', 'pages', etc.
$slug = $this->getSlug($request);
// GET THE DataType based on the slug
$dataType = DataType::where('slug', '=', $slug)->first();
// Check permission
Voyager::can('browse_'.$dataType->name);
// Next Get the actual content from the MODEL that corresponds to the slug DataType
$dataTypeContent = (strlen($dataType->model_name) != 0)
? app($dataType->model_name)->latest()->get()
: DB::table($dataType->name)->get(); // If Model doest exist, get data from table name
$view = 'voyager::bread.browse';
if (view()->exists("voyager::$slug.browse")) {
$view = "voyager::$slug.browse";
}
return view($view, compact('dataType', 'dataTypeContent'));
}
But getSlug method does not work. This error will be shown
ErrorException in GroupsController.php line 23:
Trying to get property of non-object
I guess after overriding Controlles getSlug() does not work and I have to set the slug manually
$slug = 'groups';

How to create a page in a prestashop module such that the output is not wrapped in the site's template html AND using translation?

What I know to do:
1) Create a module controller that allows translation.
I can declare texts to translate either in the controller itself or in the template:
/modules/mymodule/controllers/front/list.php
class myModuleListModuleFrontController extends ModuleFrontController
{
public function initContent()
{
parent::initContent();
$this->l('Some text to translater');
$this->setTemplate('list.tpl');
}
}
/modules/mymodule/views/templates/front/list.tpl
{l s='Some other text' mod='mymodule'}
2) I know to create some output that is not embedded in html, like for instance some json object:
/modules/mymodule/json.php
include( '../../config/config.inc.php' );
echo json_encode(array('key' => 'Some text'));
What I need:
I need to be able to translate some text AND have the output sent to the browser without the surrounding html. I have to be able to do one of those:
use a standalone file and be able to declare text to translate, similar to this (does not work):
include( '../../config/config.inc.php' );
echo json_encode(array('key' => l('Some text')));
use a module controller and force raw output, similar to this (does not work either):
class myModuleListModuleFrontController extends ModuleFrontController
{
public function initContent()
{
parent::initContent();
$this->noHtml = true;
echo json_encode(array('key' => l('Some text')));
}
}
If you want to translate text in FrontController, you can only do it in two ways:
Translate the texts inside a template
// Inside module front controller
$template = '.../template.tpl'
$this->context->smarty->fetch($template)
// Inside template.tpl
{l s='Translateable text' mod='mymodule'}
Or use strings already translated inside main module file
// Inside module front controller
$this->module->l('My string');
// But it has to already exist inside mymodule.php
$this->l('My string'); // You don't have to use it, it just has to exist to get scanned by RegEx.
If you want to return something back to Ajax request in your module front controller
public function init() {
parent::init(); // If you need to
// Some code here
if (Tools::getValue('ajax'))
{
header('Content-Type: text/html');
die($this->context->smarty->fetch($template));
// Or
header('Content-Type: application/json');
die(Tools::jsonEncode($response_array));
}
There is also a function called
FrontControllerCore::getLayout # Line 1209
Which you can use to override the whole page template, however, it should be used to create unique display for products and other page (like full screen product presentation, etc.)
If you want to ouput a file yourself while not providing a full file path to the user:
public function init() {
parent::init(); // If you need to
if (ob_get_level() && ob_get_length() > 0)
ob_end_clean();
// Set download headers
header('Content-Transfer-Encoding: binary');
header('Content-Type: '.$mime_type);
header('Content-Length: '.filesize($file));
header('Content-Disposition: attachment; filename="'.$filename.'"');
// Prevents max execution timeout, when reading large files
set_time_limit(0);
$fp = fopen($file, 'rb');
while (!feof($fp))
echo fgets($fp, 16384);
exit;
Apart from that, I don't image what else would tou possibly need to build your app. Always send token to your controllers for security!

how to use Yiic message command with CDbMessageSource

i used to use CPhpMessageSource but i want to try CDbMessageSource i though i just have to change this...
'components' => array(
'message' => array(
// 'class' => 'CPhpMessageSource',
'class' => 'CDbMessageSource',
),
But when i exectute Yiic message to insert translation data in the database it still generate files in protected/messages/"files".php
...
i must have miss one point...
i follow this http://www.yiiframework.com/doc/api/1.1/CDbMessageSource
Even though Yii has a "reader" for database translations, it doesn't have a "writer". What I usually end up doing is writing some code that can populate the tables using the generated translation files.
You can also write a derivated "message" command for Yii and use that to insert in the database directly, it's not that much work:
<?php
Yii::import('system.cli.commands.MessageCommand', TRUE);
class DbMessageCommand extends MessageCommand
{
protected function generateMessageFile($messages,$fileName,$overwrite,$removeOld,$sort)
{
if (preg_match('#/(..)/([^\\/:"*?<>|]+?)\.php$#i', $fileName, $matches))
{
$language = $matches[1];
$category = $matches[2];
foreach ($messages as $message)
{
// $message contains the string, $category has the category and $language is the current language
// Add to your DB here
}
}
}
}
Just create a DbMessageCommand.php file in your commands subdirectory and finish the code and you should be in business.
In short, what this does is use the regular message command to parse the files, but when the generateMessageFile-function is called to write to the php file, it uses a regexp to determine what would be written (it's called per language/category) and adds it in the database.
I haven't included that code, because I don't use the models as they are included in Yii. I have my own CDbMessageSource-variant and my own string tables.

kohana Auth with automodeler ORM

New to kohana here. I have a task from my internship to make login system with kohana framework 3.2 . I also did it to insert,update and delete stuff with auto modeler ORM. I have some trouble now with kohana auth. I already have the database structure Imported and inserted an user in the 'users' table and give him a role in the 'roles_user' table.
Also created an Auth.php file in APP/config/ :
return array(
'driver' => 'AutoModeler_ORM',
'hash_method' => 'sha256',
'hash_key' => 'Somebiglonghaskeyofmixedcharacters102345567709',
'lifetime' => 1209600,
'session_type' => Session::$default,
'session_key' => 'auth_user',
);
In my controller , I have a login function with the following code:
if ($_POST)
{
$post = $this->request->post();
$success = Auth::instance()->login($post['email'], $post['password']);
if ($success)
{
echo "Welcome!";
}
else
{
echo "Something goes wrong...";
}
}
I already have activated the modules in the bootstrap.
pastebin link to my role model : http://pastebin.com/bQYReETh
pastebin link to my user model : http://pastebin.com/ufzvKjmA
The problem is that I always come in the else.
Does somebody have an idea whats going on?
Do I miss something?
#Woodle,
Maybe adding a _constructor can help.
public function __construct($id = NULL)
{
if ($id !== NULL)
{
$this->load(db::select_array($this->fields())->where($this->_table_name.'.username', '=', $id));
}
elseif ($this->id) // We loaded this via mysql_result_object
{
parent::__construct($id);
}
}