Twig "Unable to add function" - php

I'm using twig, and i'm attempting to add a function.
$Func = new \Twig_SimpleFunction('placeholder', function ($title) {
$this->module->CurrentPage->addPlaceholder($title);
});
\App::make('twig')->addFunction($Func);
I will get the following exception
Unable to add function "placeholder" as extensions have already been initialized.
I've checked twice that the "addFunction" is executed before the twig "loadTemplate". So, it does not seem to be the problem.
Does anyone have a hint, or an idea about this? Or what its all about.
Thanks in advance.

You need to add twig functions right after you created Twig_Environment instance. For example, the following WILL NOT work:
$loader = new Twig_Loader_Filesystem($this->resourceRoot . '/views');
$twig = new Twig_Environment($loader, array(
'cache' => storage_path('twig'),
'debug' => Config::get('app.debug'),
'strict_variables' => true,
));
$lexer = new Twig_Lexer($twig, array(
'tag_comment' => array('{#', '#}'),
'tag_block' => array('{%', '%}'),
'tag_variable' => array('{^', '^}'),
'interpolation' => array('#{', '}'),
));
$twig->setLexer($lexer);
$function = new Twig_SimpleFunction('widget', function ($widget, array $params) {
WidgetFactory::renderWidget($widget, $params);
});
$twig->addFunction($function);
Because Lexer is initialized before functions are added. You need to make it like this:
$loader = new Twig_Loader_Filesystem($this->resourceRoot . '/views');
$twig = new Twig_Environment($loader, array(
'cache' => storage_path('twig'),
'debug' => Config::get('app.debug'),
'strict_variables' => true,
));
$function = new Twig_SimpleFunction('widget', function ($widget, array $params) {
WidgetFactory::renderWidget($widget, $params);
});
$twig->addFunction($function);
$lexer = new Twig_Lexer($twig, array(
'tag_comment' => array('{#', '#}'),
'tag_block' => array('{%', '%}'),
'tag_variable' => array('{^', '^}'),
'interpolation' => array('#{', '}'),
));
$twig->setLexer($lexer);

Related

How do I configure default query parameters with Guzzle 6?

Migrating from 5 to 6, and I've run into a snag and can't find the relevant docs.
Guzzle docs here, http://guzzle.readthedocs.io/en/latest/quickstart.html#creating-a-client, site that we can add "any number of default request options".
I want to send "foo=bar" with every request. E.g.:
$client = new Client([
'base_uri' => 'http://google.com',
]);
$client->get('this/that.json', [
'query' => [ 'a' => 'b' ],
]);
This will generate GET on http://google.com/this/that.json?a=b
How do I modify the client construction so that it yields:
http://google.com/this/that.json?foo=bar&a=b
Thanks for your help!
Alright, so far, this works here:
$extraParams = [
'a' => $config['a'],
'b' => $config['b'],
];
$handler = HandlerStack::create();
$handler->push(Middleware::mapRequest(function (RequestInterface $request) use ($extraParams) {
$uri = $request->getUri();
$uri .= ( $uri ? '&' : '' );
$uri .= http_build_query( $extraParams );
return new Request(
$request->getMethod(),
$uri,
$request->getHeaders(),
$request->getBody(),
$request->getProtocolVersion()
);
}));
$this->client = new Client([
'base_uri' => $url,
'handler' => $handler,
'exceptions' => false,
]);
If anyone knows how to make it less sinister-looking, I would say thank you!
I found a nice solution here.
Basically, anything defined in the first array of arguments, become part of the config for the client.
this means you can do this when initialising:
$client = new Client([
'base_uri' => 'http://google.com',
// can be called anything but defaults works well
'defaults' => [
'query' => [
'foo' => 'bar',
]
]
]);
Then, when using the client:
$options = [
'query' => [
'nonDefault' => 'baz',
]
];
// merge non default options with default ones
$options = array_merge_recursive($options, $client->getConfig('defaults'));
$guzzleResponse = $client->get('this/that.json', $options);
It's woth noting that the array_merge_recursive function appends to nested arrays rather than overwrites. If you plan on changing a default value, you'll need a different utility function. It works nicely when the default values are immutable though.
A "less sinister-looking" example based on the answer by #Saeven and the comment from #VladimirPak.
$query_defaults = [
'a' => $config['a'],
'b' => $config['b'],
];
$handler = \GuzzleHttp\HandlerStack::create();
$handler->push(\GuzzleHttp\Middleware::mapRequest(function (\Psr\Http\Message\RequestInterface $request) use ($query_defaults) {
$query = \GuzzleHttp\Psr7\Query::parse($request->getUri()->getQuery());
$query = array_merge($query_defaults, $query);
return $request->withUri($request->getUri()->withQuery(\GuzzleHttp\Psr7\Query::build($query)));
}));
$this->client = new \GuzzleHttp\Client([
'base_uri' => $url,
'handler' => $handler,
'exceptions' => false,
]);
I'm not sure how less sinister-looking it is though. lol
the solution proposed in github looks pretty ugly. This does not look much better, but at least is more readable and also works. I'd like feedback if anyone knows why should not be used:
$query = $uri . '/person/id?personid=' . $personid . '&name=' . $name;
return $result = $this->client->get(
$query
)
->getBody()->getContents();

Alias "components.HybridAuthIdentity" is invalid

I am following this tutorial http://www.yiiframework.com/wiki/459/integrating-hybridauth-directly-into-yii-without-an-extension/
into my own application but I get an error and I spend many hours to find wich step that I miss.
Here is my error.
Alias "components.HybridAuthIdentity" is invalid. Make sure it points to an existing directory or file.
In components directory, I create a file named HybridAuthIdentity.php
class HybridAuthIdentity extends CUserIdentity{`
public $hybridAuth;
public $adapter;
public $userProfile;
public $allowedProviders = array('google', 'facebook', 'linkedin', 'yahoo', 'live',);
protected $config;
function __construct()
{
$path = Yii::getPathOfAlias('ext.hybridauth');
require_once $path . '/hybridauth/Hybrid/Auth.php';
$this->config = array(
"base_url" => "touchtalent.dev/login/SocialLogin",
"providers" => array(
"LinkedIn" => array(
"enabled" => true,
"keys" => array (
"key" => "My key",
"secret" => "my secret id",
),
),
),
"debug_mode" => false,
"debug_file" => "",
);
$this->hybridAuth = new Hybrid_Auth($this->config);
}
}
In my siteController, I write :
Yii::import('components.HybridAuthIdentity');
$haComp = new HybridAuthIdentity;
if(!$haComp->validateProviderName($_GET['provider']))
{
throw new CHttpException("500", "Invalid action. Please Try again");
}
else
{
$haComp->adaptor = $haComp->hibrydAuth->authenticate($_GET['provider']);
$haComp->userProfile = $haComp->adaptor->getUserProfile();
$haComp->login();
$this->redirect('create');
}
How I can fix it? Thanks for all resposes...

PHP Xml-RPC array and struct

I am using XML-RPC Lib for PHP to use online signature.
This is the official doc :
$doc = array(
"content" => new xmlrpcval($doc_content, "base64"),
"name" => new xmlrpcval($doc_name, "string")
);
$language = "fr";
$signers = array(new xmlrpcval($signer, "struct"));
$request = array(
"documents" => new xmlrpcval(array(new xmlrpcval($doc, "struct")), "array"),
...
But now I want to put several documents in the request. Here is my code :
$docs = array();
foreach ($documents as $document)
{
// Signature field
$field = array(
'page' => new xmlrpcval($document->page, 'int'),
'x' => new xmlrpcval($document->x, 'int'),
'y' => new xmlrpcval($document->y, 'int'),
'label' => new xmlrpcval($document->nom, 'string'),
);
// Document
$docs []= new xmlrpcval(array(
'content' => new xmlrpcval($document->content, 'base64'),
'name' => new xmlrpcval($document->nom, 'string'),
'signatureFields' => new xmlrpcval($field, 'array'),
),'struct');
}
$request = array(
'documents' => new xmlrpcval($docs, 'array'),
And I catch this error :
Message: Call to a member function serialize() on a non-object
Does someone allready used this library ? Cause I am lost right now..
I have come to realise that even if we have an array still for using the phpxmlrpc library, we need to define the array individually, so if one has to pass an array here is what can be done,
$listids // this was my one dimensional array
$subs_list_array = array();
foreach ($listids as $id) {
$subs_list_array[] = new xmlrpcval($id, "int");
}
$msg = new xmlrpcmsg(
"contact.subscribe", array(
//Set user id
new xmlrpcval($registration_id, "int"),
new xmlrpcval($subs_list_array, "array")// <- Now I am able to use the array
)
);
For recursive encoding of php arrays, you can also use the php_xmlrpc_encode function that will recursively convert arbitrarily deep data structures

Couldn't extend session timeout in ZF2

I'm saving my session data on my database(mongodb), the customer asked that he want the system to be idle for 2 hours(he has videos on the site which may take 2 hours to finish, so he asked to set session timeout value as 2 hour). I did it as Zend Framework suggested. see my config.php below
return array(
'env2_session' => array(
'config' => array(
'class' => 'Zend\Session\Config\SessionConfig',
'options' => array(
'name' => 'test',
'remember_me_seconds' => 7200,
'gc_maxlifetime' => 7200,
),
),
'mongo_handler' => array(
'options' => array(
'class' => 'Zend\Session\SaveHandler\MongoDBOptions',
'collection' => 'sessions',
),
),
'save_handler' => 'Env2Session/Mongo/Handler',
'validators' => array(
array(
'Zend\Session\Validator\RemoteAddr',
'Zend\Session\Validator\HttpUserAgent',
),
),
),
);
But this is not the correct code as I couldn't see the session extended. it still get timed out after 24 minutes.
It will work if I add 'cookie_lifetime' => 7200 after 'gc_maxlifetime' => 7200 But this get timedout even if I'm using the site.
I want the timeout only when the system is idle. Please get me some thing on this.
Here is the save handler code which I written in Module.php
public function getServiceConfig()
{
return array(
'factories' => array(
'Env2Session/Mongo/Handler' => function ($sm) {
$config = $sm->get('config');
$session = $config['env2_session'];
$mongo = $sm->get('Env2\Mongo');
$class = isset($session['mongo_handler']['options']['class']) ? $session['mongo_handler']['options']['class'] : 'Zend\Session\SaveHandler\MongoDBOptions';
$options = array();
$options['collection'] = $session['mongo_handler']['options']['collection'];
$options['database'] = $config['db']['mongo']['db_name'];
$mongoOption = new $class($options);
$sessionSaveHandler = new MongoDB($mongo, $mongoOption);
return $sessionSaveHandler;
},
'Env2Session' => function ($sm) {
$config = $sm->get('config');
if (isset($config['env2_session'])) {
$session = $config['env2_session'];
$sessionConfig = null;
if (isset($session['config'])) {
$class = isset($session['config']['class']) ? $session['config']['class'] : 'Zend\Session\Config\SessionConfig';
$options = isset($session['config']['options']) ? $session['config']['options'] : array();
$sessionConfig = new $class();
$sessionConfig->setOptions($options);
}
$sessionStorage = null;
if (isset($session['storage'])) {
$class = $session['storage'];
$sessionStorage = new $class();
}
$sessionSaveHandler = null;
if (isset($session['save_handler'])) {
$sessionSaveHandler = $sm->get($session['save_handler']);
}
$sessionManager = new SessionManager($sessionConfig, $sessionStorage, $sessionSaveHandler);
if (isset($session['validator'])) {
$chain = $sessionManager->getValidatorChain();
foreach ($session['validator'] as $validator) {
$validator = new $validator();
$chain->attach('session.validate', array($validator, 'isValid'));
}
}
} else {
$sessionManager = new SessionManager();
}
Container::setDefaultManager($sessionManager);
return $sessionManager;
}
),
);
}
I was struggling with the same issue for zend session timeouts. Finally I implemented own solution for this case. I set up the expiration time which is refreshed during each request. But if user is not active, the time will expire and session will be destroyed.
I put all tutorial how to do it here: http://blog.tulikowski.com/zend-framework-2-implementation-of-session-authentication-timeouts/
Go to your autoload/global.php and either create or edit this key:
'session_config' => array
(
'cache_expire' => 60*60*2,
'name' => 'sessionName',
'cookie_lifetime' => 60*60*2,
'gc_maxlifetime' => 60*60*2,
'cookie_path' => '/',
'cookie_secure' => FALSE,
'remember_me_seconds' => 60*60*2,
'use_cookies' => true,
),

Doctrine 2, creating EntityManager from PDO - error

I have the following scenario:
class ModelManager extends EntityManager implements ModelManagerInterface
{
public function __construct($conn, $options = array())
{
$isDev = empty($options['is_dev']) ? false : $options['is_dev'];
// #see Doctrine\ORM\EntityManager#create()
$config = ArrayUtils::arrayMergeRecursiveRight($options, array(
'cache' => $isDev ? new Cache\ArrayCache : new Cache\ApcCache,
'queryCache' => $isDev ? new Cache\ArrayCache : new Cache\ApcCache,
'modelsProxiesPath' => getcwd() . '/cache/ModelProxies',
));
// create Configuration object
if (is_array($options)) {
$config = $this->initConfig($options);
if (!$config->getMetadataDriverImpl()) {
throw ORMException::missingMappingDriverImpl();
}
}
// test EventManager object
$eventManager = empty($options['eventManager']) ? new EventManager() : $options['eventManager'];
switch (true) {
case ($conn instanceof \PDO):
$conn = array(
'driver' => 'pdo_' . $conn->getAttribute(\PDO::ATTR_DRIVER_NAME),
'pdo' => $conn,
);
print_r($conn);
$conn = \Doctrine\DBAL\DriverManager::getConnection($conn, $config, $eventManager);
break;
case (is_string($conn)):
$pdo = new \PDO($conn);
if ('oci8' !== $pdo->getAttribute(\PDO::ATTR_DRIVER_NAME)) {
$conn = array(
'driver' => 'pdo_' . $pdo->getAttribute(\PDO::ATTR_DRIVER_NAME),
'pdo' => $pdo,
);
} else {
$conn = $this->mapDsnToDoctrine($conn);
}
$conn = \Doctrine\DBAL\DriverManager::getConnection($conn, $config, $eventManager);
break;
case (is_array($conn)):
$conn = \Doctrine\DBAL\DriverManager::getConnection($conn, $config, $eventManager);
break;
case ($conn instanceof Connection):
if ($eventManager !== null && $conn->getEventManager() !== null) {
throw ORMException::mismatchedEventManager();
}
break;
default:
throw new Exception\InvalidArgument("Invalid argument: " . json_encode($conn));
}
// parent constructor
// #see Doctrine\ORM\EntityManager#__construct()
parent::__construct($conn, $config, $conn->getEventManager());
}
// ...
}
This is used smth like this:
self::$em = new ModelManager(
new \PDO(self::$config['db_adapter']['connection']['dsn']),
empty(self::$config['db_adapter']['options']['doctrine']) ?
array() : self::$config['db_adapter']['options']['doctrine']
);
$tool = new \Doctrine\ORM\Tools\SchemaTool(self::$em);
$classes = $this->db(self::$config['db_adapter']['options']['doctrine']['modelsPath']);
$tool->updateSchema($classes);
Where the config looks like this:
$config = array(
'db_adapter' => array(
'connection' => array(
'dsn' => 'mysql://root:******#localhost/netistest' . time(),
),
'options' => array(
'doctrine' => array(
'cache' => 'ArrayCache|ApcCache', // development|testing&production
'queryCache' => 'ArrayCache|ApcCache', // development|testing&production
'modelsPath' => __DIR__ . '/NetisTest/Model',
'modelsProxiesPath' => __DIR__ . '/cache/doctrine/ModelProxies',
'modelsProxiesNamespace' => 'App\Models\Proxies',
'modelsProxiesAutogenerate' => 'App\Models\Proxies',
),
'zend' => array(
// at this moment we decided not to implement Zend\DbAdapter
),
)
),
);
The problem with all this strange configuration, is that, after instantiating the ModelManager class, when trying to interrogate the database for creating the tables associated to my models, it throws the following error:
Doctrine\DBAL\DBALException: An exception occurred while executing 'SHOW FULL TABLES WHERE Table_type = 'BASE TABLE'':
SQLSTATE[3D000]: Invalid catalog name: 1046 No database selected
/home/dragosc/workspace/athem-repositories/Component_NetisDb/vendor/doctrine/dbal/lib/Doctrine/DBAL/DBALException.php:91
/home/dragosc/workspace/athem-repositories/Component_NetisDb/vendor/doctrine/dbal/lib/Doctrine/DBAL/Connection.php:699
/home/dragosc/workspace/athem-repositories/Component_NetisDb/vendor/doctrine/dbal/lib/Doctrine/DBAL/Connection.php:630
/home/dragosc/workspace/athem-repositories/Component_NetisDb/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/AbstractSchemaManager.php:206
/home/dragosc/workspace/athem-repositories/Component_NetisDb/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/AbstractSchemaManager.php:250
/home/dragosc/workspace/athem-repositories/Component_NetisDb/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/AbstractSchemaManager.php:986
/home/dragosc/workspace/athem-repositories/Component_NetisDb/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/SchemaTool.php:855
/home/dragosc/workspace/athem-repositories/Component_NetisDb/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/SchemaTool.php:832
/home/dragosc/workspace/athem-repositories/Component_NetisDb/tests/NetisTest/Db/Setup/Doctrine.php:51
You can find the code (however in an older form) here as well:
https://github.com/athemcms/Component_NetisDb/blob/master/library/Netis/Db/ModelManager/ModelManager.php
Can anyone please help me in understanding why PDO isn't enough for EntityManager to remember the database as well ?
Thanks a lot in advance!

Categories