Symfony write to parameters.yaml from controller - php

I want to write an integer value from a controller to parameters.yaml. Is that even possible?
Example:
parameters.yaml
parameters:
# ...
counter: 13
SomeController.php
class SomeController
{
public function indexAction()
{
$counter = $this->getParameter('counter');
$counter++;
// now save new counter value to parameters.yaml !??
}
}

Parameters are generally fixed values.
So A better approach is probably writing into an individual yaml file:
http://symfony.com/doc/current/components/yaml/introduction.html
use Symfony\Component\Yaml\Dumper;
const MY_PARAM=13;
//manipulate and do your thing....
$array=['my_param'=>self::MY_PARAM++];
$dumper = new Dumper();
$yaml = $dumper->dump($array);
file_put_contents('/path/to/file.yml', $yaml);
Then you read the file wherever you need it in your application.
use Symfony\Component\Yaml\Parser;
$yaml = new Parser();
$value = $yaml->parse(file_get_contents('/path/to/file.yml'));

Parameters.yml must contain only fixed configuration values ! You should store your counter in database or (i don't like this) in txt file.
But if you really want to edit it. You have to parse the file and search / replace the line ... It's really a bad practice !

Related

PrestaShop AdminController - is there better way to preserve backslashes and html entites?

I'm creatin a Prestashop module for my e-store; I've created module's own AdminController-inheritor class with standart List and Form views to manage module settings, and the ObjectModel-inheritor class to store setings in DB. All works good until I have to store text fields with folowing symbols: \ < >
The problem is that HelperForm spoiles the clean data retrieved from DB by using Tools::getValue() that applies stripslashes, without adding slashes to clean data.
I temporary solved problem with following:
to save < > symbols I just use self::TYPE_HTML definition in my ObjectModel; This is good declarative solution (I just define field options, and controller does everything the way I need);
but to save backslashes I have to use such interception:
.
public function getFieldValuePreserveSlashes($obj, $key, $id_lang = null) {
if ($id_lang)
$default_value = (isset($obj->id) && $obj->id && isset($obj->{$key}[$id_lang])) ? $obj->{$key}[$id_lang] : false;
else
$default_value = isset($obj->{$key}) ? $obj->{$key} : false;
$default_value = addslashes($default_value);
Tools::mapValue($key, 'addslashes');
return Tools::getValue($key.($id_lang ? '_'.$id_lang : ''), $default_value);
}
public function getFieldValue($obj, $key, $id_lang = null) {
if($key === 'export_params_text')
return $this->getFieldValuePreserveSlashes($obj, $key, $id_lang);
else
return parent::getFieldValue($obj, $key, $id_lang);
}
It works but I guess it is not the best way (I still hope there is some more native way, something like some options that I could set and not to duplicate core-functions code just to add 2 strings :)
PS I didnt forget about this after I solved a local task because I have such problem often enough, and if I dont want to use global override to place desired logic ther, I have to copy-paste this code from one controller to another, and this dont let me sleep calmly :)
Thanks in advance:)

Automatically loading the classes

I've built "core" class that loads another classes, and I want to load automatically all the classes in spesific folder named "class", I've started to build something, but I have no idea if it's good.
In the construct function at the core class, I'm getting an array with the class names to load.
The construct function calls to function named _loadClasses, and in the _loadClasses function, I'm loading the classes by using require_once() fucntion.
Then at the top of the page, i'm adding public variable with the name of the class.
For example, "public $example;"
Now, what left is to create the ocject of the class, so that's what I did.
Example of the _loadClasses method:
require_once("class/user.class.php");
self::$user = new User();
Here comes the "automat" part.
I want the function _loadClasses to get an array, for example:
private function _loadClasses( $classesToLoad = array('security', 'is') );
and now, I'm using glob to load the classes from the folder "class", the name syntax of the classes files in the folder "class" is classname.class.php.
$classesArray = array(); // initialize the variable of all the web classes
$classesFiles = glob("class/*.php"); // gets all the web classes from the folder 'class'
foreach($classesFiles as $file) { // loop on the classes in the folder 'class'
$filename = explode('class/', $file);
$filename = $filename[1];
$className = explode('.class.php', $filename);
$className = $className[0];
if($className != 'index.php' || $className != 'database') {
array_push( $classesArray, $className ); // adds the class name into the array 'classesArray'
}
}
foreach( $classesArray as $className ) {
if( in_array($className, $classesToLoad) ) {
require_once("class/$className.class.php");
$classLines = file( "class/$className.class.php" );
$classNameLine = $classLines[1];
$classNameLine = explode(' ', $classNameLine);
$classObjectName = $classNameLine[1];
$classObjectName = explode(" ", $classObjectName);
self::$$classObjectName = new $classObjectName();
}
}
I need something like that, of curse it doesn't work, it's just to show you what I wanna do with an example. Thanks in advance.
For this particular approach I'd suggest something like:
// Your custom class dir
define('CLASS_DIR', 'class/')
// Add your class dir to include path
set_include_path(get_include_path().PATH_SEPARATOR.CLASS_DIR);
// You can use this trick to make autoloader look for commonly used "My.class.php" type filenames
spl_autoload_extensions('.class.php');
// Use default autoload implementation
spl_autoload_register();
To get started there's no need to implement a parent class autoloading functionality for "core" objects since they should only be aware of their role functionality. Use php standard library.
For this purposes you can use the __autoload() function. It will be called when you create a new object.
__autoload($class)
{
require 'dir/to/your/classes/'. $class. '.php'
}
You have to use one class per file and name the files the same as the class they describe.
"it doesn't work" is not a useful diagnostic. What doesn't work? What's the error message? Which line does it fail at? Looking at the code, the first loop, though a little messy (why do you have a file named index.php in this directory? Why don't you just glob for *.class.php?) should probably work OK. But the second loop is horrible.
To start with, why load all the filenames into an array in one loop, then use a second loop to load some of them? As for reading the class file to determine the object name....words fail me. Simply name it as the filename without the .class.php
$classesFiles = glob("class/*.class.php"); // gets all the web classes from the folder 'class'
foreach($classesFiles as $file) {
$prefix=array_shift(explode('.', basename($file)));
if (in_array($prefix, $classestoload)
&& !isset($this->$prefix)) {
if (!class_exists($prefix)) {
require($file);
}
$this->$prefix=new $prefix();
}
}
You could use the autoloader, but this will get messy if you integrate with other code which also uses the autoloader, but in a different way.

How to get TYPO3 settings in the utility files?

plugin.tx_xxx {
setting {
storagePid = 23
}
}
I want this TYPO3 settings in utility file.
Please help me.
The above method works only in controller or services class try below it will work in any PHP files in Extension.
$objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\Extbase\\Object\\ObjectManager');
$configurationManager = $objectManager->get('TYPO3\\CMS\\Extbase\\Configuration\\ConfigurationManager');
$extbaseFrameworkConfiguration = $configurationManager->getConfiguration(\TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface::CONFIGURATION_TYPE_FULL_TYPOSCRIPT);
$storagePid = $extbaseFrameworkConfiguration['plugin.']['tx_guesthouse_guesthouse.']['settings.']['storagePid'];
You can add below line in the your controller.
$objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager');
$configurationManager = $objectManager->get('TYPO3\\CMS\\Extbase\\Configuration\\ConfigurationManager');
$setting = $configurationManager->getConfiguration(\TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface::CONFIGURATION_TYPE_SETTINGS);
$ts_config = $setting['plugin.']['tx_xxxx.']['settings.']['storagePid'];
I think it will helpful to you. You can also used this typo3 settings in the services files as well.
Only for TYPO3 Backend
For multi domain set root before obtaining configuration
$configurationManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Configuration\\BackendConfigurationManager');
$configurationManager->currentPageId = ROOT_PID_OF_YOUR_DOMAIN;
$extbaseFrameworkConfiguration = $configurationManager->getTypoScriptSetup();
//Following will be resultant array, find your required stuff from it
print_r($extbaseFrameworkConfiguration);
Note: Don't forget to extend your class with \TYPO3\CMS\Extbase\Configuration\BackendConfigurationManager in
order to obtain access for it's protected variables
Now,In Typo3 8.X, currentPageId is protected so, we could not set it directly, and there would not be any set method defined in core class. Following is correct code as per new version that may help you. Thanks for the correct direction.
$configurationManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Configuration\\BackendConfigurationManager');
\TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump($configurationManager);
$configurationManager->getDefaultBackendStoragePid();
$extbaseFrameworkConfiguration = $configurationManager->getTypoScriptSetup();
//Following will be resultant array, find your required stuff from it
\TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump($extbaseFrameworkConfiguration);
In any TYPO3 version including 10, one may use this one-liner:
$GLOBALS['TSFE']->tmpl->setup['plugin.']['tx_xxxx.']['settings.']['storagePid'];
To get rid of the dots, use TypoScriptService, thus
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\TypoScript\TypoScriptService;
$typoScriptService = GeneralUtility::makeInstance(TypoScriptService::class);
$typoScriptSettings = $typoScriptService->convertTypoScriptArrayToPlainArray($GLOBALS['TSFE']->tmpl->setup);
$storagePid = $typoScriptSettings['plugin']['tx_xxxx']['settings']['storagePid'];
You can also only load the CONFIGURATION_TYPE_SETTINGS:
$objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\Extbase\\Object\\
ObjectManager');
$configurationManager = $objectManager->get('TYPO3\\CMS\\Extbase\\Configuration\\ConfigurationManager');
$pluginSettings = $configurationManager->getConfiguration(\TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface::CONFIGURATION_TYPE_SETTINGS, null, 'tx_guesthouse_guesthouse');
$storagePid = $pluginSettings['storagePid'];
IMHO this is more effective because it does not load the whole TS tree.

Zend Framework 1 pass parameters using get to the route

I hope the title does not sound too confusing, but I had no idea how to name my problem.
Brief intro:
I'm using Zend 1.1X.
At the moment I've been working with a search form sending few parameters via POST.
Now I have to change it to use GET, I have a route created looking similar to that:
"search/what/:what/shape/:shape"
and so on, I also have 2 optional parameters which takes null as default.
I'm trying to generate an URL (using Zend View Helper Url) at form's action, but it throws an exception:
Uncaught exception 'Zend_Controller_Router_Exception' with message what is not specified
I Now don't have idea what should I do. If I change my route to "search" only, it then sends the form correctly, but I end up with "search?what=XXXX&shape=YYYY" instead of "search/what/XXXX/shape/YYYY".
Is there any way that could be handled the way I like??? :>
#EDIT
I think this should also be mentioned - I have a different form, similar one, pointing to a route without parameters specified as well and the uri gets "translated" to the form of "key/value" pairs. The only difference between them is that the first one does not use Url helper, instead has the method part hard-coded and my form is being submitted programatically (button => jQuery stuff => submit). Would that make a difference here, as I believe it should not? :>
I hope any possible source of this behaviour will come up to you, because I'm really stuck at the moment and I simply can't find what's wrong..
Thanks in advance!
With the GET method a form generates an url like this: action?param1=val1&param2=val2&....
I see two solutions:
The first is to regenerate the URL by javacsript, we can imagine something like this:
<form method="get" id="id_form">
....
</form>
<script>
var objet_form = document.getElementById('id_form');
function gestionclic(event){
var url = objet_form.action;
for(var i = 0; i < objet_form.length; i++){
url += "/" + objet_form[i].name + "/" + objet_form[i].value;
}
objet_form.action = url;
}
if (objet_form.addEventListener){
objet_form.addEventListener("submit", gestionclic, false);
} else{
objet_form.attachEvent("onsubmit", gestionclic, false);
}
</script>
But I don't think this is a good solution.
The second is to manage it with a plugin:
For the plugin, it must be declared in the bootstrap.
For example:
public function _initPlugins(){
$front = Zend_Controller_Front::getInstance();
$front->registerPlugin(new Application_Plugin_PRoutage());
}
with this example, the application/plugins folder, create the PRoutage.php plugin like this:
class Application_Plugin_PRoutage extends Zend_Controller_Plugin_Abstract
{
public function dispatchLoopStartup(Zend_Controller_Request_Abstract $request)
{
...
}
}
and with the variable $request you have access to your data as an array with $request->getParams().
We can imagine something like this:
public function dispatchLoopStartup(Zend_Controller_Request_Abstract $request)
{
$param = $request->getParams();
$what = "";
$shape = "";
if (isset($param['what']) $what = $param['what'];
if (isset($param['shape']) $shape = $param['shape'];
if ($what == "XXXX" && $shape == "YYYY"){
$request->setControllerName('other_controler')
->setActionName('other_action')
->setDispatched(true) ;
}
}
I hope it will help you

PHP Hook Function

Can I basically do something like:
register_function_hook('myFunctionHook');
so then when any function is run:
functionA(); //The hook runs myFunctionHook();
anoterFunction(); //The hook runs myFunctionHook();
Class::functionA(); //The hook runs myFunctionHook();
Does such a thing exist?
-- Edit --
What I want to do is to get a breakdown of durations of each function. Ie. Performance Tuning. I want to get an idea of what takes all the time without installing xDebug on my Apache server, however I don't know if it is possible.
It's possible with register_tick_function(), also check this comment on the PHP manual:
$script_stats = array();
$time = microtime(true);
function track_stats(){
global $script_stats,$time;
$trace = debug_backtrace();
$exe_time = (microtime(true) - $time) * 1000;
$func_args = implode(", ",$trace[1]["args"]);
$script_stats[] = array(
"current_time" => microtime(true),
"memory" => memory_get_usage(true),
"file" => $trace[1]["file"].': '.$trace[1]["line"],
"function" => $trace[1]["function"].'('.$func_args.')',
"called_by" => $trace[2]["function"].' in '.$trace[2]["file"].': '.$trace[2]["line"],
"ns" => $exe_time
);
$time = microtime(true);
}
declare(ticks = 1);
register_tick_function("track_stats");
// the rest of your project code
// output $script_stats into a html table or something
This "hooks" to everything, not just functions but I think it fits your purpose.
No, its not possible the way you like
But You can achieve something close with inheritance.
class Vehicle {
function __construct() {
$this->hookFunction();
}
function hookFunction() {
//
}
}
class Car extends Vehicle {
}
Class Toyota extends Car {
}
new Toyota(); // will you hook function
// this exclude static call to member functions, or other inline functions.
What you looking for is called profiler. And PQP looks like one, which is standalone.
Instead of polluting the code, you should use a real Profiler, like that one provided by xdebug
Not sure if the Topic Starter needs this anymore, but perhaps others can still benefit from this.
There is a PHP lib, written completely in PHP, that allows you to do exactly what you want.
Here's an article about how it works, including the source code:
http://phpmyweb.net/2012/04/26/write-an-awesome-plugin-system-in-php/
It allows you to register a function from a class to be hooked. So it basically executes your code first, and then you determine wether you want to call the original function too after your code has been executed.

Categories