Cron Et Variables De Sessions

Bonjour à tous !

Je reviens vers vous pour un nouveau problème qui fait suite à mon ancien post.

Je dois dorénavant mettre en place un cron pour que ma base de donnée se remplisse automatiquement.

Le problème c’est que ma solution utilise setState() et getState() qui sont des variables de sessions => pas compatibles avec un cron…

Quelqu’un aurait une idée pour contourner ce problème ?

Merci d’avance !

Salut !

Est-il vraiment nécessaire d’utiliser des valeurs en session à l’aide de getState/setState ?

Si oui, alors tu vas devoir réaliser une sorte de contournement au cas où Yii::app()->user n’est pas défini, du genre :




if (isset(Yii::app()->user)) {

    $store = Yii::app()->user->getState('Store');

} else {

    $store = 'store1';

}



Sinon je pense qu’il faudrait revoir le système de manière à stocker ce “store” directement dans ta classe Product de manière à pouvoir “router” vers la base de ton choix à la volée.




class Product extends BaseProduct

{

    public $store;


    ...


    public function getDbConnection()

    {

        //$store = Yii::app()->user->getState('Store');

        $store = $this->store;

        ...



Et donc juste après avoir instancié l’objet, tu définis le store :




$product = new Product;

$product->store = 'store1';



Salut !

Merci d’avoir répondu !

Ta deuxième solution est celle que j’avais implémenté à la base et que je n’ai jamais réussi à faire fonctionner car j’avais beaucoup de conflits avec ActiveRecord…

Et la première solution ne fonctionnera pas, car il n’y a pas de table par défaut… je dois toutes les remplir…

Je pense quand même qu’il faudrait que tu persistes dans la deuxième solution car à mon sens c’est celle qui a le plus de chances d’aboutir. Essaye si tu veux et dis moi quelle erreur ça lève, et on essayera de régler ça.

Solution trouvée… jusqu’au prochain problème…!

(Il s’agissait de ta première suggestion RadicalDingos)

Dans ma config j’ai déclaré une connexion à une autre base de donnée :




'components' => array(


    //Base de donnée principale

    'db' => array(

        'connectionString' => 'mysql:host=' . HOST . ';dbname=' . BASE,

        'username' => USER,

        'password' => PASS,

        'charset' => 'utf8'

    ),

    //Base de donnée d'un magasin spécifique

    'dbsecond' => array(

        'class' => 'CDbConnection',

        'connectionString' => 'mysql:host=' . HOST . ';dbname=' . BASE.'%s',

        'autoConnect' => false,

        'username' => USER,

        'password' => PASS,

        'charset' => 'utf8'

    )

),

//Permet de réattribuer un nouveau magasin sans REGEX

'params' => array(

    'ConnectionString' => 'mysql:host=' . HOST . ';dbname=' . STORE.'%s',

);



Je peux moduler ma connexion à la base de donnée secondaire en fonction du magasin, avec sprintf :




$dbsecond = Yii::app()->dbsecond;

$dbsecond->active = false;

$dbsecond->connectionString = sprintf(Yii::app()->params['ConnectionString'], $store);

$dbsecond->active = true;



Et pour tous les modèles communs à toutes les bases de données des magasins, j’ai crée une classe dans components qui étend la classe GxActiveRecord :




abstract class StoreGxActiveRecord extends GxActiveRecord  {


    public static $dbsecond;


    public function getDbConnection()

    {

        if (self::$dbsecond!==null)

            return self::$dbsecond;

        else

        {

            self::$dbsecond=Yii::app()->dbsecond;

            if (self::$dbsecond instanceof CDbConnection)

                return self::$dbsecond;

            else

                throw new CDbException(Yii::t('yii','Active Record requires a "db" CDbConnection application component.'));

        }

    }


}



et chaque modèle étend cette nouvelle classe.




abstract class BaseProduct extends StoreGxActiveRecord

{

    public static function model($className=__CLASS__)

    {

        return parent::model($className);

    }


...}




Du coup, plus de variable de sessions =) et toutes mes classes ont été allégées !!

Et du coup tu vas pouvoir exécuter ton cron. Je te conseille pour cela la création d’une commande console, héritant de CConsoleCommand (un peu de doc là).

Exactement ! Merci RadicalDingos !

Bonjour

En reprenant la suggestion de classe “Store” en réponse à la question dans le lien mentionné dans le billet initial, il est possible d’adapter “Store” même:




	public static $current_store;


        public static function getCurrentStoreDb() {

   		$app=Yii::app();

            if(!$app instanceof CConsoleApplication) {

                $store=$app->getUser()->getState('Store');;

            } else {

   			$store = self::$current_store;

            }

     		return self::getStoreDb($store);

        }

$current_store correspond à la boutique actuelle en cours de traitement. Cette valeur pourrait venir d’un paramètre en ligne de commande, ou bien être définit lors d’une boucle (Store::$current_store=‘store2’).