Symfony task on the hosting - symfony1

I have task:
<?php
require_once(dirname(__FILE__).'/../../config/ProjectConfiguration.class.php');
class GroupCheckTask extends sfBaseTask
{
protected function configure()
{
// // add your own arguments here
// $this->addArguments(array(
// new sfCommandArgument('my_arg', sfCommandArgument::REQUIRED, 'My argument'),
// ));
$this->addOptions(array(
new sfCommandOption('application', null, sfCommandOption::PARAMETER_REQUIRED, 'The application name'),
new sfCommandOption('env', null, sfCommandOption::PARAMETER_REQUIRED, 'The environment', 'dev'),
new sfCommandOption('connection', null, sfCommandOption::PARAMETER_REQUIRED, 'The connection name', 'doctrine'),
// add your own options here
));
$this->namespace = '';
$this->name = 'GroupCheck';
$this->briefDescription = '';
$this->detailedDescription = <<<EOF
The [GroupCheck|INFO] task does things.
Call it with:
[php symfony GroupCheck|INFO]
EOF;
}
protected function execute($arguments = array(), $options = array())
{
$databaseManager = new sfDatabaseManager($this->configuration);
$connection = $databaseManager->getDatabase($options['connection'])->getConnection();
// add your code here
$users= Doctrine::getTable('sfGuardUserProfile')->getUserDelay() ;
foreach($users as $sfGuardUserProfile)
{
$users_id =$sfGuardUserProfile-> getUserId();
$userForChange = Doctrine::getTable('sfGuardUserGroup')->getUserForChange($users_id) ;
foreach($userForChange as $sfGuardUserGroup)
{
$sfGuardUserGroup->setSfGuardGroup(Doctrine::getTable('sfGuardGroup')- >findOneByName('basic'))->save();
}
}
}
}
And in my localhost all works fine, but it is not work in hosting. What is the correct way to run task on hosting from cron tab?

first, you dont need put the line require_once(dirname(__FILE__).'/../../config/ProjectConfiguration.class.php');
second, write a namespace for your task is a good practice
third, you need the the a php file like:
<?php
/* /path/to/file.php */
chdir("/the/path/in/your/host/to/symfony/project");
exec("symfony your_namespace:GroupCheck");
?>
last, you can put this file in your crontab
00 59 23 * * php /path/to/file.php

Related

ZF2/3 Load Modules from Database

I would like to know if there is a way to load modules from a database table in zend framework 2 preferable 3? I want to be able to dynamically disable or enable modules based on a status column inside a database table
I'm pretty sure you can accomplish this by attaching listener to some of ModuleManager events.
There are docs for v3 https://docs.zendframework.com/zend-modulemanager/module-manager/ and v2 https://framework.zend.com/manual/2.1/en/modules/zend.module-manager.module-manager.html
And don't forget autoloading for v3
By reading your question tom_cruz, I realize that I have exactly the same one ;-)
I went through the ZF2 source code of ModuleManager, ModuleManagerFactory, ModuleEvent and some listeners. After analyzing the flow, my new question is:
"What do I expect from an active/inactive module?"
Nearly every important stuff is done by the events Nemutaisama mentioned. i.e. loading config by adding getConfig() Method to the Module.php class.
ATM I'm not able to answer the above question. I'll come back to this one laters. But right now, I think it's an application problem, not a framework one.
I have done this some time ago by:
Create a "Core" Module responsible with fetching modules from database.
1.1 In the Module.php add module listener
public function init(ModuleManagerInterface $manager)
{
$sharedEventManger = $manager->getEventManager()->getSharedManager();
$sharedEventManger->attach(ModuleManager::class, ModuleEvent::EVENT_LOAD_MODULES_POST, new ModuleListener(), 10000);
}
Module Listener created by me was something like:
public function __invoke(ModuleEvent $event)
{
$target = $event->getTarget();
$serverName = $_SERVER['SERVER_NAME'];
if(! $serverName) { return; }
//module ok
if(! $target instanceof ModuleManagerInterface) { return; }
//config data
$configListener = $event->getConfigListener();
$config = $configListener->getMergedConfig(false);
//app modules
$modules = $target->getModules();
//select active modules
$adapter = new Adapter($config['db']);
$sql = new Sql($adapter);
$select = $sql->select(['c' => 'customers'])
->join(['cm' => 'customers_modules'], 'cm.customer_id = c.id', ['module' => 'module'])
->where(['c.domain' => $serverName])
->where(['cm.active' => 1]);
$statement = $sql->prepareStatementForSqlObject($select);
$result = $statement->execute();
if($result instanceof ResultInterface && $result->isQueryResult() && $result->getAffectedRows()) {
//change db connection params here (if you use different db for customers)
while ($current = $result->current()) {
if (! in_array($current['module'], $modules)) {
try {
$target->loadModule($current['module']) ;
} catch (\RuntimeException $e) {
$target->loadModule('WQ' . str_replace($current['prefix'], '', $current['module']));
}
$modules[] = $current['module'];
$module = $target->getModule($current['module']);
if (($module instanceof ConfigProviderInterface) || (is_callable([$module, 'getConfig']))) {
$moduleConfig = $module->getConfig();
$config = ArrayUtils::merge($config, $moduleConfig);
}
}
$result->next();
}
}
$target->setModules($modules);
$configListener->setMergedConfig($config);
}
Hope it was useful.

Zend 2 After login how to set user

I have the following code and which works, but now the next step.
How and where do i have to set a session so the script "sees" that the user is already logged in?
if ($form->isValid()) {
$securePass = $this->getUsersTable()->getUserByUsername( $this->params()->fromPost('username') );
if( $securePass ){
$bcrypt = new Bcrypt();
if ($bcrypt->verify( $this->params()->fromPost('password') , $securePass->password)) {
$sm = $this->getServiceLocator();
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$authAdapter = new AuthAdapter(
$dbAdapter,
'users',
'username',
'password'
);
$authAdapter
->setIdentity($securePass->username)
->setCredential($securePass->password);
$result = $authAdapter->authenticate($authAdapter);
echo $result->getIdentity() . "\n\n";
}
else {
}
The Zend way of doing it is to use Authentication component that handles this for you.
http://framework.zend.com/manual/current/en/modules/zend.authentication.intro.html
This will allow you to check if user is logged in (you will have to setup the authentication adapter first):
use Zend\Authentication\AuthenticationService;
// TODO set-up authentication adapter
$auth = new AuthenticationService()
$identity = $auth->getIdentity();
For accessing post data you should also leverage the framework instead of accessing $_POST directly. In your controller:
$this->params()->fromPost('username');
$this->params()->fromPost('password');
This will guide you through the whole process of adding authentication layer to your app:
https://zf2.readthedocs.org/en/latest/modules/zend.authentication.adapter.dbtable.html
Using the AuthenticationService provided by Zend, setting the user in the PHP session is automatically taken care of.
A good thing to understand the authentication mechanism would be to read, and code along with this introduction to authentication:
http://framework.zend.com/manual/current/en/modules/zend.authentication.intro.html#adapters
In a custom AuthenticationAdapter "setting the user in the session", or identity persistence, would be done by returning \Zend\Authentication\Result with the result of the authentication and the user identity in the authenticate() method.
$user = $this->userService->findByEmail($this->email);
if($user !== false) {
if($this->encryption->verify($this->password, $user->getPassword()) {
return new Result(Result::SUCCESS, $user);
}
return new Result(Result::FAILURE, null);
}
$this->userService being the UserService that leads to the UserMapper
(more about Services: http://framework.zend.com/manual/current/en/in-depth-guide/services-and-servicemanager.html)
$user being the User entity with the encrypted password stored
$this->encryption being your encryption method (Zend\Crypt\Password\Bcrypt for example)
$this->email being the email/username provided by the form
$this->password being the password provided by the form
Result being Zend\Authentication\Result
This is an easy approach. More detailed Result types are:
/**
* General Failure
*/
const FAILURE = 0;
/**
* Failure due to identity not being found.
*/
const FAILURE_IDENTITY_NOT_FOUND = -1;
/**
* Failure due to identity being ambiguous.
*/
const FAILURE_IDENTITY_AMBIGUOUS = -2;
/**
* Failure due to invalid credential being supplied.
*/
const FAILURE_CREDENTIAL_INVALID = -3;
/**
* Failure due to uncategorized reasons.
*/
const FAILURE_UNCATEGORIZED = -4;
/**
* Authentication success.
*/
const SUCCESS = 1;
LoginController.php
if ($form->isValid()) {
$securePass = $this->getUsersTable()->getUserByUsername( $this->params()->fromPost('username') );
if( $securePass ){
$bcrypt = new Bcrypt();
if ($bcrypt->verify( $this->params()->fromPost( 'password' ) , $securePass->password ) ) {
$sm = $this->getServiceLocator();
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$authAdapter = new AuthAdapter(
$dbAdapter,
'users',
'username',
'password'
);
$authAdapter->setIdentity($securePass->username)
->setCredential($securePass->password);
$result = $authAdapter->authenticate($authAdapter);
$sesssionData = $authAdapter->getResultRowObject();
$auth = new AuthenticationService();
$storage = $auth->getStorage();
$storage->write($sesssionData);
return $this->redirect()->toRoute('user_list');
}
}
}
public function onBootstrap(MvcEvent $e)
{
$eventManager = $e->getApplication()->getEventManager();
$moduleRouteListener = new ModuleRouteListener();
$moduleRouteListener->attach($eventManager);
$app = $e->getParam('application');
$app->getEventManager()->attach('render', array($this, 'setLayoutTitle'));
$eventManager->attach(MvcEvent::EVENT_DISPATCH, array($this, 'checkLogin'));
}
public function checkLogin(MvcEvent $e)
{
$iden = new AuthenticationService();
if( $iden->getIdentity() === NULL ){
$matches = $e->getRouteMatch();
$controller = $matches->getParam('controller');
$getController = explode( '\\', $controller );
if( isset( $getController[2] ) && $getController[2] != 'Login' ){
$controller = $e->getTarget();
return $controller->plugin('redirect')->toRoute('login');
}
}
}

Inquirer.js: Allow users to write a list response

Alright I'm stuck creating a yeoman generator. I have a prompt that brings up a list of three different options to choose from. It looks like this:
Name of JS file:
- One
- Two
- Other
I want the third one to allow the option to allow the user to write their own. Mabye I can call another prompt method?
// ****************************************************************************
// Author: Daniel Jenkins
// Date: 03/35/3015
// Purpose: A generator for creating js files including, name, date, and purpose fields.
// ****************************************************************************
var generators = require('yeoman-generator');
module.exports = generators.Base.extend({
prompting: function() {
var done = this.async();
var myChoices = [this.appname, 'one', 'two', 'other'];
var prompts = {
type: 'list',
name: 'fileName',
message: 'Name of new JS file: ',
choices: myChoices
};
// Select the filename from list.
this.prompt(prompts, function(answers) {
// Store user input as an argument for the EJS preprossor.
this.context = {
fileName: answers.fileName,
};
done();
}.bind(this));
},
// Add file after filling in EJS template
copyMainFiles: function() {
// Create a time object for todays date.
var my_date = new Date();
// Add date property.
this.context.fileDate = my_date.toDateString();
// Run through EJS and create the file.
this.template("_index.js", this.context.fileName + ".js", this.context);
}
});
You can use when, to specify another field is called when by running a conditional statement. If the statement return true the field will be called else it will be skipped.
See the addition to your code:
module.exports = generators.Base.extend( {
prompting : function () {
var done = this.async();
var myChoices = [ this.appname, 'one', 'two', 'other' ];
var prompts = [ {
type : 'list',
name : 'fileName',
message : 'Name of new JS file: ',
choices : myChoices
},{
when : function ( answers ) {
return answers.fileName === 'other';
},
type : 'input',
name : 'fileName',
message : 'custom file name'
}];
// Select the filename from list.
this.prompt( prompts, function ( answers ) {
// Store user input as an argument for the EJS preprossor.
this.context = {
fileName : answers.fileName,
};
done();
}.bind( this ) );
},
// Add file after filling in EJS template
copyMainFiles : function () {
// Create a time object for todays date.
var my_date = new Date();
// Add date property.
this.context.fileDate = my_date.toDateString();
// Run through EJS and create the file.
this.template( "_index.js", this.context.fileName + ".js", this.context );
}
} );

Quickbooks PHP Integration error " No registered functions for action"

I want to connect to database of Quickbooks desktop version using PHP. For this Iam using the PHP dev kit downloaded from the link http://consolibyte.com/downloads/quickbooks-php-devkit/ .
Here I connected to Quickbooks databse successfully using the given code in inside docs/example_app_web_connector folder. In it adding of customer to databse is working. But when I tried to add function for fetching all employees from the database, it shows error like No registered functions for action.
Where should I include this function to work perfectly??
In functions page I coded like this:-
function _quickbooks_customer_query_response($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
{
if (!empty($idents['iteratorRemainingCount']))
{
// Queue up another request
$Queue = QuickBooks_WebConnector_Queue_Singleton::getInstance();
$Queue->enqueue(QUICKBOOKS_QUERY_CUSTOMER, null, 0, array( 'iteratorID' => $idents['iteratorID'] ));
}
// This piece of the response from QuickBooks is now stored in $xml. You
// can process the qbXML response in $xml in any way you like. Save it to
// a file, stuff it in a database, parse it and stuff the records in a
// database, etc. etc. etc.
//
// The following example shows how to use the built-in XML parser to parse
// the response and stuff it into a database.
// Import all of the records
$errnum = 0;
$errmsg = '';
$Parser = new QuickBooks_XML_Parser($xml);
if ($Doc = $Parser->parse($errnum, $errmsg))
{
$Root = $Doc->getRoot();
$List = $Root->getChildAt('QBXML/QBXMLMsgsRs/CustomerQueryRs');
foreach ($List->children() as $Customer)
{
$values = array(
'ListID' => $Customer->getChildDataAt('CustomerRet ListID'),
'FullName' => $Customer->getChildDataAt('CustomerRet FullName'),
'FirstName' => $Customer->getChildDataAt('CustomerRet FirstName'),
'LastName' => $Customer->getChildDataAt('CustomerRet LastName'),
);
print_r($values);
foreach ($Customer->children() as $Node)
{
// Be careful! Custom field names are case sensitive!
if ($Node->name() === 'DataExtRet' and
$Node->getChildDataAt('DataExtRet DataExtName') == 'Your Custom Field Name Goes Here')
{
$values['Your Custom Field Names Goes Here'] = $Node->getChildDataAt('DataExtRet DataExtValue');
}
}
$fullname=$values['FullName'];
$firstname=$values['FirstName'];
$lastname=$values['LastName'];
$listid=$values['ListID'];
// Do something with that data...
mysql_query("INSERT INTO `my_customer_table` (name,fname,lname,quickbooks_listid) VALUES ('$fullname','$firstname','$lastname','$listid') ");
exit;
}
}
return true;
}
And in main code called like this
:-
require_once dirname(FILE) . '/config.php';
$Queue = new QuickBooks_WebConnector_Queue($dsn);
$fg=$Queue->enqueue(QUICKBOOKS_QUERY_CUSTOMER);
Sorry for trouble.. atlast got it... Actually In that folder their is a file named qbwc.php that I didnt noticed. In it we have to add functions inside $map variable...
<?php
require_once dirname(__FILE__) . '/config.php';
/**
* Require some callback functions
*/
require_once dirname(__FILE__) . '/functions.php';
// Map QuickBooks actions to handler functions
$map = array(
QUICKBOOKS_ADD_CUSTOMER => array( '_quickbooks_customer_add_request', '_quickbooks_customer_add_response' ),
QUICKBOOKS_QUERY_CUSTOMER => array( '_quickbooks_customer_query_request', '_quickbooks_customer_query_response' ),
);
// This is entirely optional, use it to trigger actions when an error is returned by QuickBooks
$errmap = array(
'*' => '_quickbooks_error_catchall', // Using a key value of '*' will catch any errors which were not caught by another error handler
);
// An array of callback hooks
$hooks = array(
);
// Logging level
$log_level = QUICKBOOKS_LOG_DEVELOP; // Use this level until you're sure everything works!!!
// What SOAP server you're using
$soapserver = QUICKBOOKS_SOAPSERVER_BUILTIN; // A pure-PHP SOAP server (no PHP ext/soap extension required, also makes debugging easier)
$soap_options = array( // See http://www.php.net/soap
);
$handler_options = array(
'deny_concurrent_logins' => false,
'deny_reallyfast_logins' => false,
); // See the comments in the QuickBooks/Server/Handlers.php file
$driver_options = array( // See the comments in the QuickBooks/Driver/<YOUR DRIVER HERE>.php file ( i.e. 'Mysql.php', etc. )
);
$callback_options = array(
);
// Create a new server and tell it to handle the requests
// __construct($dsn_or_conn, $map, $errmap = array(), $hooks = array(), $log_level = QUICKBOOKS_LOG_NORMAL, $soap = QUICKBOOKS_SOAPSERVER_PHP, $wsdl = QUICKBOOKS_WSDL, $soap_options = array(), $handler_options = array(), $driver_options = array(), $callback_options = array()
$Server = new QuickBooks_WebConnector_Server($dsn, $map, $errmap, $hooks, $log_level, $soapserver, QUICKBOOKS_WSDL, $soap_options, $handler_options, $driver_options, $callback_options);
$response = $Server->handle(true, true);
?>

Zend2: how to render view wrapped in layout into a variable?

I need to save all rendered content (layout + view) in a variable to save it with Zend_Cache, I can't use Varnish, nginx or other software to do so. Currently I'm doing it like that:
$view->setTemplate('application/index/index');
$viewContent = $renderer->render($view);
$view = $this->getEvent()->getViewModel();
$view->content = $viewContent;
$content = $renderer->render($view);
Can anyone suggest me more elegant solution? Mb catching native render event with EventManager or some tricks with Response object or dispatch event? Would like to hear all suggestions.
Thanks!
Add two listeners to your Module class. one listener checks early, just after route if the match is one that's cached. The second listener waits for render and grabs the output to store it in cache:
namespace MyModule;
use Zend\Mvc\MvcEvent;
class Module
{
public function onBootstrap(MvcEvent $e)
{
// A list of routes to be cached
$routes = array('foo/bar', 'foo/baz');
$app = $e->getApplication();
$em = $app->getEventManager();
$sm = $app->getServiceManager();
$em->attach(MvcEvent::EVENT_ROUTE, function($e) use ($sm) {
$route = $e->getRouteMatch()->getMatchedRouteName();
$cache = $sm->get('cache-service');
$key = 'route-cache-' . $route;
if ($cache->hasItem($key)) {
// Handle response
$content = $cache->getItem($key);
$response = $e->getResponse();
$response->setContent($content);
return $response;
}
}, -1000); // Low, then routing has happened
$em->attach(MvcEvent::EVENT_RENDER, function($e) use ($sm, $routes) {
$route = $e->getRouteMatch()->getMatchedRouteName();
if (!in_array($route, $routes)) {
return;
}
$response = $e->getResponse();
$content = $response->getContent();
$cache = $sm->get('cache-service');
$key = 'route-cache-' . $route;
$cache->setItem($key, $content);
}, -1000); // Late, then rendering has happened
}
}
Just make sure you register a cache instance under cache-service in the service manager. You can update above example to check during the render event if the route is in the $routes array. Now you just check if the cache has the key, which might be slower than doing in_array($route, $routes) like during the render event.

Resources