How to translate $url_handlers? - silverstripe

I have a situation where I need to translate the following $url_handlers for different countries.
So on an english site the URL looks like this: http://website.com/gyms/boston/group-training
I need to be able to translate the "group-training" part of the URL. I have translated the rest of the site using the _t() method throughout.
My current setup:
class GymLocationPage_Controller extends Page_Controller {
private static $allowed_actions = array(
'currentSpecials',
'sevenDayFreeTrial',
'groupTraining'
);
private static $url_handlers = array(
'current-specials' => 'currentSpecials',
'trial' => 'sevenDayFreeTrial',
'group-training' => 'groupTraining'
);
}
How would one achieve this?

You could update the config inside the controller's init() function, doing something like this:
public function init() {
parent::init();
// Define your translated actions.
$translatedCurrentSpecials = _t('Actions.CURRENT_SPECIALS', 'aktuella-kampanjer');
$translatedSevenDayFreeTrial = _t('Actions.SEVEN_DAY_TRIAL', 'sjudagars-prova-pa-period');
// Define your url handlers.
$urlHandlers = $this->config()->url_handlers;
$translatedUrlHandlers = [
$translatedCurrentSpecials => 'currentSpecials',
$translatedSevenDayFreeTrial => 'sevenDayFreeTrial'
];
// Update the config.
Config::inst()->update(
$this->class,
'url_handlers',
$translatedUrlHandlers + $urlHandlers // Important to prepend and not append.
);
}

Related

Can I with fzaninotto/Faker generate doc / xls files?

Reading docs for laravel 9 site at
https://github.com/fzaninotto/Faker
I did not find if there is a way to generate doc(microsoft word) / xls(microsoft excel) files with this library ?
Maybe some other library ?
Thanks in advance!
Faker is using to generate simple data like sentences, email, phone etc. But you can use, for example maatwebsite/excel to make xlsx filling it with faker.
The simplest way to create doc file is to make html file with doc extension.
Update:
Keep in mind that maatwebsite/excel was built for Laravel framework, but there are other packages witch can be used independent from frameworks, for example XLSWriter
maatwebsite/excel
Laravel's factory to make User model
class UserFactory extends Factory
{
protected $model = User::class;
public function definition()
{
return [
'login' => '0'.$this->faker->numberBetween(70000000000, 80000000000),
'email' => $this->faker->unique()->safeEmail,
'lastname' => $this->faker->lastName,
'firstname' => $this->faker->firstNameMale,
'phone' => $this->faker->phoneNumber,
];
}
}
maatwebsite's export class (this one uses a collection as source)
use Maatwebsite\Excel\Concerns\FromCollection;
class UsersExport implements FromCollection
{
private $collection;
public function __construct($collection)
{
$this->collection = $collection;
}
public function collection()
{
return $this->collection;
}
}
Make xlsx file with 10 users uses laravel's seeder
class XlsSeeder extends Seeder
{
public function run()
{
$users = User::factory()
->count(10)
->make();
Excel::store(new UsersExport($users), 'users.xlsx');
}
}
XLSWriter
Wherever you need to create xlsx, you can write something like:
for($i = 0; $i < 10; $i++) {
$users[] = [
$faker->numberBetween(70000000000, 80000000000),
$faker->unique()->safeEmail,
$faker->lastName,
$faker->firstName,
$faker->phoneNumber,
];
}
$fileObject = new \Vtiful\Kernel\Excel([
'path' => './tests'
]);
$file = $fileObject->fileName('users.xlsx', 'sheet_one')
->header(['login', 'email', 'lastname', 'firstname', 'phone'])
->data($users);
$file->output();

How to sort images as part of a many_many in silverstripe?

I have created a $many_many array for $slideImages on my home page. After much reading and trying I am still unable to tell the CMS the order I want the images to appear in the template. By default they are sorted by upload date I believe.
I can create the gridfield but I can't seem to get a textfield to enter in a sorting number. Right now I just finished a rabbit trail that led me to gridFieldComponent but I get an error and the docs are not helping me.
use SilverStripe\Assets\Image;
use SilverStripe\AssetAdmin\Forms\UploadField;
use SilverStripe\Forms\TextField;
use SilverStripe\Forms\GridField\GridFieldComponent;
use SilverStripe\Forms\GridField\GridFieldConfig_RelationEditor;
use SilverStripe\Forms\GridField\GridField;
class HomePage extends Page
{
private static $db = [];
private static $has_one = [];
private static $many_many = [
'SliderImage'=>Image::Class
];
private static $owns = [
'SliderImage'
];
private static $many_many_extraFields= [
'SliderImage'=>array(
'Sort'=>'Int'
)
];
public function getCMSFields(){
$fields = parent::getCMSFields();
$fields->addFieldToTab('Root.Attachments', UploadField::create('SliderImage', 'Sllider Images')->setFolderName('HomePageSlides'));
$gridFieldConfig = GridFieldConfig_RelationEditor::create()->addComponents(
new GridFieldComponent(TextField('Sort'))
);
$gridField = new GridField("SliderImage", "Slider Image", $this->SliderImage()->sort('Sort'), $gridFieldConfig);
$fields->addFieldToTab("Root.Attachments", $gridField);
return $fields;
}
}
The Error I get is:
"Uncaught Error: Cannot instantiate interface
SilverStripe\Forms\GridField\GridFieldComponent"
As per wmk's comment, your are missing a new or ::create on the TextField initialization for your Sort field.
Should be:
new GridFieldComponent(new TextField('Sort'))
Or better yet:
GridFieldComponent::create(TextField::create('Sort'))

SilverStripe: Trying to implement Contact Form function but getting white screen of death

I'm following this tutorial
I have a page called 'Contact.ss'. The php file looks like this:
class Contact extends Page {
private static $has_one = array (
'Photograph' => 'Image'
);
static $db = array (
'MailTo' => 'Varchar(100)',
'SubmitText' => 'Text'
);
public function getCMSFields() {
$fields = parent::getCMSFields();
$fields->addFieldToTab('Root.Main', $Photograph = UploadField::create('Photograph'), 'Content');
$Photograph->getValidator()->setAllowedExtensions(array('png','jpeg','jpg','gif'));
$Photograph->setFolderName('photographs');
$fields->addFieldToTab("Root.Main", new Textfield('Mailto', 'Address to email contact form submission to'));
$fields->addFieldToTab("Root.Main", new TextareaField('SubmiteText', 'Text displayed after contact form submission'));
return $fields;
}
}
class Contact_Controller extends Page_Controller {
static $allowed_actions = array(
'ContactForm'
);
function ContactForm() {
// Create fields
$fields = new FieldSet(
new TextField('Name', 'Name*'),
new EmailField('Email', 'Email*'),
new TextareaField('Comments','Comments*')
);
// Create action
$actions = new FieldSet(
new FormAction('SendContactForm', 'Send')
);
// Create Validators
$validator = new RequiredFields('Name', 'Email', 'Comments');
return new Form($this, 'ContactForm', $fields, $actions, $validator);
}
}
But when I call $ContactForm in the template I get a blank screen when I try to load the page. (500 error)
I've checked to see if it's possible to call the function from the template by replacing all the ContactForm()'s code with:
return "Hello, World!"
It works, so I know the function is being called. But I can't see what's wrong with the code from the tutorial.
Can anyone help me out?
The issue is the tutorial you have used is written for SilverStripe 2.4 while you are using a newer version, SilverStripe 3.1.
For SilverStripe 3.1 I suggest going through the SilverStripe Frontend Forms lesson rather than the SSBits tutorial. The SSBits tutorial is from 2010 and is for SilverStripe 2.4. The SilverStripe Frontend Forms lesson is from 2015 and is for the current version of SilverStripe.
With your current code there are a number of bits of code that need to be updated to work in the latest version of SilverStripe.
FieldSet has been replaced by FieldList. You will need to replace each instance of FieldSet with FieldList in your code.
Your ContactForm should look more like this:
function ContactForm() {
// Create fields
$fields = FieldList::create(
TextField::create('Name', 'Name*'),
EmailField::create('Email', 'Email*'),
TextareaField::create('Comments','Comments*')
);
// Create action
$actions = FieldList::create(
FormAction::create('SendContactForm', 'Send')
);
// Create Validators
$validator = RequiredFields::create('Name', 'Email', 'Comments');
return Form::create($this, 'ContactForm', $fields, $actions, $validator);
}
In SilverStripe 3.1 the in built static variables need to be declared private.
Make sure you declare your $allowed_actions as private:
private static $allowed_actions = array(
'ContactForm'
);
As well as your $db as private:
private static $db = array (
'MailTo' => 'Varchar(100)',
'SubmitText' => 'Text'
);

Symfony 2 Sonata admin list views do not display subclasses

Currently I cant get subclasses to appear in a list view using sonta admin bundle for symfony 2
I can get it working for create forms as per the advanced config page (http://sonata-project.org/bundles/admin/2-1/doc/reference/advance.html) but how can you do this with the list view?
If i pass the subclass in the url - list?subclass=MySubClassName
and set the object in my listAction
$object = $this->admin->getNewInstance();
$this->admin->setSubject($object);
I can get the subject and configure the correct fields with configureListFields()
if ($subject instanceof MySubClassName) {
$listMapper->add('MySubClassNameID');
$listMapper->add('MySubClassNameKey');
$listMapper->add('MySubClassNameStatus','text');
}
but the end results table is always blank and the symfony debug toolbar seems to show that the db queries are looking for the parent class. Anyone got this to work?
I'm not sure what you mean with those "subclasses" in the list view, but if you want to add a field form another entity (connected through a foreign key with yours) you can do it lie this:
$listMapper
->addIdentifier('id')
->addIdentifier('title')
->add('name')
->add('entity1.customField1')
->add('entity2.customField2');
Incase anyone else faces this I found out how to do this.
To make it work in a way similar to the edit page you would pass the subclass in the url
...list?subclass=MySubClass
set the subject of your listAction in your custom admin crud controller
public function listAction()
{
if (false === $this->admin->isGranted('LIST')) {
throw new AccessDeniedException();
}
if ($listMode = $this->getRequest()->get('_list_mode')) {
$this->admin->setListMode($listMode);
}
$this->admin->setSubject($this->admin->getNewInstance());
$datagrid = $this->admin->getDatagrid();
$formView = $datagrid->getForm()->createView();
// set the theme for the current Admin Form
$this->get('twig')->getExtension('form')->renderer->setTheme($formView, $this->admin->getFilterTheme());
return $this->render($this->admin->getTemplate('list'), array(
'action' => 'list',
'form' => $formView,
'datagrid' => $datagrid,
'csrf_token' => $this->getCsrfToken('sonata.batch'),
));
}
and then over-ride the createQuery method in your Admin class
public function createQuery($context = 'list')
{
$cName = get_class($this->getSubject());
$query = $this->getModelManager()->createQuery($cName);
foreach ($this->extensions as $extension) {
$extension->configureQuery($this, $query, $context);
}
return $query;
}
If you pass anything with url parameters you should also override getPersistentParameters to add your url request to Pager, FilterForm and the form for batchActions (or others that appear on the list view)
<?php
class YourAdmin extends Admin
{
public function getPersistentParameters()
{
if (!$this->getRequest()) {
return array();
}
return array(
'subclass' => $this->getRequest()->get('subclass'),
);
}
}

Complex search functionality

I have a class called Recipe as follows:
class Recipe extends Page {
static $db = array(
"Title" => "Text"
);
static $many_many = array(
"RecipeTypes" => "RecipeType"
);
}
And a class called RecipeType as follows:
class RecipeType extends DataObject {
static $db = array(
"Title" => "Text",
);
static $belongs_many_many = array(
"Recipes" => "Recipe"
);
}
For my site's search functionality, I want the search results to be every Recipe which has a Title that matches the search parameter, as well as every Recipe which has a RecipeType whose Title matches the search parameter.
I've tried the following:
return Recipe::get()->filterAny(array(
'Title:PartialMatch' => $searchString,
'RecipeTypes.Title:PartialMatch' => $searchString
));
But that is only returning Recipes whose Title matches the search parameter; it's not returning any Recipes where one of the Recipe's RecipeTypes' Title property matches the search parameter.
Any ideas?
Managed to get it working with the following:
$recipes_from_title = Recipe::get()->filter('Title:PartialMatch', $searchString);
$recipes_from_diet = RecipeType::get()->filter('Title:PartialMatch', $searchString)->relation('Recipes');
$matching_recipes = new ArrayList();
foreach($recipes_from_title as $recipe_from_title) {
$matching_recipes->push($recipe_from_title);
}
foreach($recipes_from_diet as $recipe_from_diet) {
$matching_recipes->push($recipe_from_diet);
}
return $matching_recipes;

Resources