Symfony 2: How to dynamically adjust configuration parameters - php

For my AppBundle (THE APPLICATION ITSELF, NOT A REUSABLE BUNDLE) I have a configuration parameter that is a path.
I'd like to be sure the path ends with a /.
In this moment I have a method in the entity that uses this path (yes is an entity and not a controller) adjust the configuration parameter with a code like this:
public function buildLogoFolder($folder)
{
// Replace the placeholder with the current Entity's URL
$folder = str_replace('{entity_domain}', $this->getDomain()->getCanonical(), $folder);
$folder = rtrim(ltrim($folder, '/'), '/') . '/';
return $folder;
}
As the $folder parameter comes from the config.yml file I'd like to move outside of the entity this adjustment.
I think I should use a solution similar to the one suggested here, that is the use of the DependencyInjection component.
I think the process is very similar to the loading of a configuration file for a new bundle as explained in the Symfony's documentation but I'm not sure on how to proceed.
Is there someone who can put me on the right way?
I'd like to automate the process. I want read the folder configuration parameter value and then adjust it with the method I wrote above.
I want to be sure that the folder parameter configured ever ends with a trailing slash, also if the developer didn't write it in the configuration.
So, If the developer write something like path/to/folder the resulting configuration parameter is automatically adjusted to path/to/folder/.

Related

The technical reason is: No template was found. View could not be resolved for action "search" in class "LoginController"

Im new to typo3 and ive been trying to develop an extension for it. When I load the plugin to the page i get and error:
Sorry, the requested view was not found.
The technical reason is: No template was found. View could not be resolved for action "search" in class "LoginController".
In the login controller i have a function searchAction and I do have a template inside
\Resources\Private\Templates\StoreInventory\Search.html
What might be the error? I followed the documentation for extension development by typo3. I even downloaded the code from GIT and tried using that but no luck.
TL;DR: It should be placed at Resources/Private/Templates/Login/Search.html
explanation:
From your question I can tell you've used the documentation on https://docs.typo3.org/m/typo3/book-extbasefluid/master/en-us/4-FirstExtension/6-adding-the-template.html
It is not wrong, but you've missed a vital step. When you take a look at the path they are using you'll see that a lot is done automagically. Let's break it down.
They have a controller with an action and a template related to it in the following path
controller:
\MyVendor\StoreInventory\Controller\StoreInventoryController
action: listAction
template: EXT:store_inventory/Resources/Private/Templates/StoreInventory/List.html
If you look closely you'll see that the template path is made up from several components.
the extension (EXT:store_inventory)
the default template directory path (Resources/Private/Templates)
The Controller name without the controller suffix (StoreInventory)
the Action name without the action suffix (List)
the .html suffix
If you take that information and apply it to your case it would be:
the extension (EXT:your_extension_name)
the default template directory path (Resources/Private/Templates)
The Controller name without the controller suffix (Login)
the Action name without the action suffix (Search)
the .html suffix
So the end result would be something like
EXT:your_extension_name/Resources/Private/Templates/Login/Search.html
It is true that you can use typoscript to change this behaviour or set overrides or extended templating for instance. But I think you're working from the default, and this should be the working path for you now
First check your templateRootPaths in Configuration/TypoScript/setup.typoscript
And set accordingly.
Try placing the file at \Resources\Private\Templates\Search.html as \Resources\Private\Templates is the default path unless you have altered it.

Create folder/Sub-folder in Code-igniter

I am a Drupal dev and new to code-igniter or any such php frameworks.
Now i have to modify an existing application done on codeigniter and the structure must be as follows:
example.com/motors
example.com/motors/car-for-sale
example.com/motors/car-for-rent etc.
Before it has only one url example.com/motors and i want to create more urls as mentioned above.
In the application\views\content folder i have the following structure:
application\views\content\motors.php
application\views\content\motors
application\views\content\motors\car-for-sale.php
In the application\controller folder i have the following structure:
application\controller\motors.php
application\controller\motors\motors.php
application\controller\motors\car-for-sale.php
I want to get the url example.com/motors & example.com/motors/car-for-sale from the files resides in the motors folder.Also how can i set a default file to load when i open example.com/motors?
You can't have a (controllers) directory that matches the name of a controller class at the same level. That is, since you have a controllers/motors.php, the files under controllers/motors/* will never be reached.
Instead (and this is the answer to your second question), you should set the default_controller name and rename controllers/motors.php to controllers/motors/<default_controller>.php.
Note that the default_controller setting points to a controller name (not a file location) and is applied to all directories. That is, if you set it to 'Default', then controllers/Default.php will be used when you open http://domain.tld/ and controllers/motors/Default.php will be used if you open http://domain.tld/motors/.
Also, your controller names MUST start with a capital letter, so default.php would be incorrect and should be Default.php instead. This might be working for you on Windows right now (because of its case-insensitive file system), but as soon as you upload your site to a Linux (or other UNIX-based) host, any classes with file names that don't start with a capital letter won't work.
It looks like you're trying to build a CodeIgniter site with a completely different paradigm from what it is designed around.
The structure you are after can be set up using the routes.php file within application/config
In there, you can set routes to go to any location needed, so for you, something like:
$routes['motors/cars-for-sale'] => 'motors/cars_for_sale';
$routes['motors/cars-for-rent'] => 'motors/cars_for_rent';
Then in application/controller you'd have a Motors.php file, which starts:
class Motors extends CI_Controller{
And also has the functions cars_for_sale and cars_for_rent
The mappings in routes sets this to link together.
In order to get the views you want for any given route, in the controller function, you'd have:
$this->load->view('path/to/view/file', $array_of_data); // view path does not need the .php extension
I'd recommend having a look and possibly even a follow through of the CodeIgniter tutorial in their documentation

How to use relative paths in symfony2?

This is going to be a short, nevertheless complicated question. Let me try and explain what I am trying to accomplish.
I've got a config file config.yml
# src/Company/HappyBundle/Resources/config/config.yml
company_happy:
import:
attachments_path: "#CompanyHappyBundle/Resources/public/attachments"
I'm trying to get the attachments_path parameter in a Command. I do this using the following line:
$this->container->getParameter('company_happy.import.attachments_path');
Now, how can I convert #CompannyHappyBundle to the actual path?
Update
If you have any information on better ways to do this, this is always welcome. What I'm trying to do is to save attachments to the bundle's public folder.
You don't need to store your attachments at the bundle's home directory. Also you have wrong definition for parameter. All parameters in Service container must be located under parameters section.
As you can see here you need to create Form with file field. Then fill this form with Request data and then use move() method upon it to move file in any location you need. The most popular place for it - web/uploads directory.
public function uploadAction()
{
$form = $this->createFormBuilder()
->add('attachment', 'file')
->getForm();
if ($form->isValid()) {
$dir = $this->container->getParameter('kernel.root_dir').'/../web/uploads';
$someNewFilename = '...';
$form['attachment']->getData()->move($dir, $someNewFilename);
// ...
}
// ...
}
Set a value in your parameters.yml as following:
# parameters.yml
parameters:
company_happy.import.attachments_path: "#CompanyHappyBundle/Resources/public/attachments"
Then call it the same in your controller as you currently are.

How do I change the URL Alias for Security/login in SilverStripe to user/login

I am working on a new website being built in SilverStripe. Currently I am having a ton of trouble trying to get the system to let me change the URL alias (or create a second one) for the Security controller's login (and eventually logout) function.
I have tried playing around with the routes.yml file and I tried creating the paths in my own UserController and loading directly from the Security controller with "return Security::login()". But that gives me errors about the use of the static functions.
Unfortunately I don't come from a ton of object oriented experience and this is the first CMS I have used that actually uses a bunch of true object orientation. The current version of SilverStripe we are using is 3.0 (but we will be upgrading to 3.1.1 in a few days).
Does anyone know much about the routing in SilverStripe?
as you stated correctly, SilverStripe has routes, and they can be defined in a yaml config file.
if you take a look at the existing routes.yml in the framework you can see how the default security route is defined:
https://github.com/silverstripe/silverstripe-framework/blob/fd6a1619cb7696d0f7e3ab344bc5ac7d9f6cfe77/_config/routes.yml#L17
if you just want to replace the Secuirty in Secuirty/login, its as easy as just creating your own routes.ymlin mysite/_config/ with the following content:
---
Name: myroutesorsomeotherrandomname
Before: '*'
After:
- '#rootroutes'
- '#coreroutes'
- '#modelascontrollerroutes'
- '#adminroutes'
---
Director:
rules:
'foobar//$Action/$ID/$OtherID': 'Security'
NOTE: make sure you ran a ?flush=1 to ensure the yml file is loaded (they get cached)
also make sure you use spaces in the yml file, if you use tabs you are going to have a bad time
if you however wish to also replace /login and /logout this is no longer a thing for routing.
login and logout are actions (php functions that are listed in Security::$allowed_actions and thus available as URL) on the on Security.
but its still rather easy, just subclass Security and create the actions you want:
<?php
class MySuperSecurity extends Security {
private static $allowed_actions = array(
'showMeTheLoginForm',
'alternative_login_action_with_dashes',
'doTheLogout',
);
function showMeTheLoginForm() {
// can be visited via http://website.com/foobar/showMeTheLoginForm
return $this->login();
}
function alternative_login_action_with_dashes() {
// can be visited via http://website.com/foobar/alternative-login-action-with-dashes
return $this->login();
}
function doTheLogout($redirect = true) {
// can be visited via http://website.com/foobar/doTheLogout
return $this->logout($redirect);
}
}
and make the route point to your new class instead of Security inside the routes.yml:
'foobar//$Action/$ID/$OtherID': 'MySuperSecurity'
NOTE: again, make sure you did a ?flush=1, both the private static $allowed_actions as well as the yml config file are cached by silverstripe.
NOTE: both solutions suggested in this post will create an additional route to login and does not replace the existing one, so the old Security/login will still be available
I don't know nothing about SilverStripe excepting that is a CMS, but i think SilverStripe must provide a way to aliases Url. Also an alternative is create Alias in virtual host definition if you're using apache or in .htaccess file. Refer to apache doc to further details. If you post a skeleton of your .htaccess file or VirtualHost definition i could help you.

How to get the server path to the web directory in Symfony2 from inside the controller?

The question is as follows:
How can I get the server path to the web directory in Symfony2 from inside the controller (or from anywhere else for that reason)
What I've already found (also, by searching here):
This is advised in the cookbook article on Doctrine file handling
$path = __DIR__ . '/../../../../web';
Found by searching around, only usable from inside the controller (or service with kernel injected):
$path = $this->get('kernel')->getRootDir() . '/../web';
So, is there absolutely no way to get at least that 'web' part of the path? What if I, for example, decided to rename it or move or something?
Everything was easy in the first symfony, when I could get like everything I needed from anywhere in the code by calling the static sfConfig::get() method..
There's actually no direct way to get path to webdir in Symfony2 as the framework is completely independent of the webdir.
You can use getRootDir() on instance of kernel class, just as you write. If you consider renaming /web dir in future, you should make it configurable. For example AsseticBundle has such an option in its DI configuration (see here and here).
To access the root directory from outside the controller you can simply inject %kernel.root_dir% as an argument in your services configuration.
service_name:
class: Namespace\Bundle\etc
arguments: ['%kernel.root_dir%']
Then you can get the web root in the class constructor:
public function __construct($rootDir)
{
$this->webRoot = realpath($rootDir . '/../web');
}
You also can get it from any ContainerAware (f.i. Controller) class from the request service:
If you are using apache as a webserver (I suppose for other
webservers the solution would be similar) and are using
virtualhosting (your urls look like this - localhost/app.php then you can use:
$container->get('request')->server->get('DOCUMENT_ROOT');
// in controller:
$this->getRequest()->server->get('DOCUMENT_ROOT');
Else (your urls look like this - localhost/path/to/Symfony/web/app.php:
$container->get('request')->getBasePath();
// in controller:
$this->getRequest()->getBasePath();
You are on Symfony, think "Dependency Injection" ^^
In all my SF project, I do in parameters.yml:
web_dir: "%kernel.root_dir%/../web"
So I can safely use this parameter within controller:
$this->getParameter('web_dir');
My solution is to add this code to the app.php
define('WEB_DIRECTORY', __DIR__);
The problem is that in command line code that uses the constant will break. You can also add the constant to app/console file and the other environment front controllers
Another solution may be add an static method at AppKernel that returns DIR.'/../web/'
So you can access everywhere
UPDATE: Since 2.8 this no longer works because assetic is no longer included by default. Although if you're using assetic this will work.
You can use the variable %assetic.write_to%.
$this->getParameter('assetic.write_to');
Since your assets depend on this variable to be dumped to your web directory, it's safe to assume and use to locate your web folder.
http://symfony.com/doc/current/reference/configuration/assetic.html
For Symfony3
In your controller try
$request->server->get('DOCUMENT_ROOT').$request->getBasePath()
$host = $request->server->get('HTTP_HOST');
$base = (!empty($request->server->get('BASE'))) ? $request->server->get('BASE') : '';
$getBaseUrl = $host.$base;
Since Symfony 3.3,
You can use %kernel.project_dir%/web/ instead of %kernel.root_dir%/../web/

Categories