Jump to content
Larry Ullman's Book Forums


  • Content Count

  • Joined

  • Last visited

  • Days Won


Everything posted by Ziggi

  1. Thank you, Antonio - sure never enough learning but this time I am pretty sure what I want. I want a tabbed "baby steps" kind of interface (you call it "achievement system") where each "achievement" is goverened by a separate model/controller. So, the step - while completed - is stored in a database rather than in persistent session data or a cookie. Best regards,
  2. ???? What is so wrong, Larry??? - Sorry - this is a completely mistery for me this time!!! Actually - you should notice that this time I was not asking for any help! I rather tried to DONATE a code. I actually SUPPORTED this forum with a very useful trick I stumbled upon once upon a time - but the trick was misunderstood by Edward. So, indeed this might be a language issue what I am unaware of - but - is it Palace de Versaille or is it The Yii Book forum for internationals who may be not so skillful in English language used by diplomatic council ??? Please, Larry - enlighten me as a native speaker where the particular offence is present: Here: "Jesus - Edward - can you get focused for a moment, please?" or rather here: "Can you cope now?" I am asking seriously as I really do not know! I rapidly browse the dictionary and neither word is listed as rude or inappropriate... Or is it unnaceptable to show "advanced user" he missed the point completely??? Because he missed it - sorry - not my fault! And really - you should already notice - I am not so eager to ask for help in terms of "gimme code, please" any more. I am myself advanced enough to ask for ideas rather than code. If you look closer, you will notice I am CONTRIBUTING code for this forum and I am supporing you with findings what are not that obvious I hope. Consequently, I would appreciate Edward reading my messages with more focus - then there would be no need to ask me (after my second attempt to explain the issue in a comprehensive manner) this way, what I consider rather nasty and patronising: "I am not following you distribution lists of what exactly?"
  3. Jesus - Edward - can you get focused for a moment, please? If you send an e-mail during add campaign you do not send it to a single addressee but to thousands of them! So you keep all these e-mail addressess in distribution lists - in tables full of e-mail addresses! And most probably you need a distribution list A for campaing X and another distribution list B for campaign Y as these are completely different customer targets! For instance list A is a list of elderly people who are looking for appropriate health programm while list B is a list of young professionals who may be interested in exclusive active holiday trip offer. And you need to be able to manage all these distribution lists in an easy manner - browse all addresses in a list, add them, remove them etc. But there may be dozens of individual distribution lists while each and every list is generally very same in its structure what is a common denominator. Consequently - rather than handling each list with a separate model it is more clever to have one model fit to this common structure and swap between database tables behind. Another solution is to keep all e-mail addresses in one huge table and keep their relation to particular campaign in an additional column but this is a risky business. Lists are imported from Excel files provided by customer - if something goes wrong during import there is a risk of table gets corrupted rendering all e-mails of all campaigns unaccessible. This is the reason why I believe keeping various distribution lists in separated tables is a less vulnerable approach. Can you cope now?
  4. You misunderstood - one table for all campaigns but each distribution list (or e-mail address list, as you like) is a separate table! Or be so kind and provide me an alternative solution to manage distribution lists efficiently!
  5. Hi, The previous script has some problem with scenarios. This is a new one what is working fine and its functionality is IMHO critical but for whatever reason is missing in Yii native code: Example usage: Presume you have a table of addvertising mailing campaigns. Each record is a separate mailing campaing: it has a unique id, unique name, unique e-mail body, it is associated with given customer, it is owned by a specific employee etc. And finally it must be associated with a specific distribution list. And each distribution list is in fact a separate database table where each record contains a specific e-mail address, addressee name, etc. So the problem is - how to create a Yii model for distribution lists? Normally one have to provide a table name while creating a model class. But here we will most probably create a new list with each and every new campaign! So - what is the solution? The solution is a dynamic active record based on code submited by Pavle Predic: <?php /** * This is the model class for table "lista_x". * * The followings are the available columns in table 'lista_x': * @property integer $id * @property string $email */ /** * CActiveRecord implementation that allows specifying * DB table name instead of creating a class for each table. * * Usage (assuming table 'lista_x' with columns 'id' and 'email'): * * $model = Lista::forTable('lista_x'); * //list existing records * foreach ($model->findAll() as $entry) * echo $entry->id . ': ' . $entry->email . '<br />'; * //add new entry * $model->email = 'john.doe@anonymus.com'; * $model->save(); */ class Lista extends CActiveRecord { /** * Name of the DB table * @var string */ protected $_tableName; /** * Table meta-data. * Must redeclare, as parent::_md is private * @var CActiveRecordMetaData */ protected $_md; /** * Constructor * @param string $scenario (defaults to 'insert') * @param string $tableName */ public function __construct($scenario = 'insert', $tableName = null) { $this->_tableName = $tableName; parent::__construct($scenario); } /** * Overrides default instantiation logic. * Instantiates AR class by providing table name * @see CActiveRecord::instantiate() * @return DynamicActiveRecord */ protected function instantiate($attributes) { return new Lista(null, $this->tableName()); } /** * Returns meta-data for this DB table * @see CActiveRecord::getMetaData() * @return CActiveRecordMetaData */ public function getMetaData() { if ($this->_md !== null) return $this->_md; else return $this->_md = new CActiveRecordMetaData($this); } public function tableName() { if (!$this->_tableName) $this->_tableName = parent::tableName(); return $this->_tableName; } /** * Returns an instance of Lista for the provided DB table. * This is a helper method that may be used instead of constructor. */ public static function forTable($tableName, $scenario = 'insert') { return new Lista($scenario, $tableName); } // rest of model class code public function rules() { return array( array('email', 'required'), array('id, email', 'safe', 'on'=>'search'), ); } public function relations() { return array( 'campaigns' => array(self::HAS_MANY, 'Campaigns', 'list_id'), ); } public function attributeLabels() { return array( 'id' => 'ID', 'email' => 'Email', ); } public function search() { $criteria=new CDbCriteria; $criteria->compare('id', $this->id); $criteria->compare('email', $this->email, true); return new CActiveDataProvider($this, array( 'criteria'=>$criteria, )); } } As this functionality is so fundamental I feel really surprised it is missing in the generic framework code!
  6. First of all - you need to double check your .htaccess as well as all Apache configuration files, especially httpd.conf file. Internal Server Error (code 500) is usually a consequence of misused rewrite rules, so the easy way is to temporary disable mode_rewrite module and check how is site performing without it. If the error is gone - you know where to look around...
  7. Hi, I need to use a model with dynamic table name in my application. I have found a piece of code to use like that: $model = new DynamicModel($tableName); The code is as follows: class DynamicModel extends CActiveRecord { private static $_tableName; public function __construct($tableName) { if(strlen($tableName) == 0) { return false; } if(strlen($tableName)>0){ self::$_tableName = $tableName; } self::setIsNewRecord(true); } public static function model($tableName) { if(strlen($tableName) == 0) { return false; } $className=__CLASS__; if(strlen($tableName)>0){ self::$_tableName = $tableName; } return parent::model($className); } public function tableName() { return '{{'.self::$_tableName.'}}'; } public function setTableName($tableName) { self::$_tableName = $tableName; } ...// The rest of model code }
  8. Antonio - sorry - I do not pretend a Yii master. I think I learn fast but sometimes one needs just a "right" clue not a "good" one. This time you gave me "good" clues while Larry's offered a "right" one! And sure - partial render is nothing special but... one have to catch the idea... ;-) Have a nice weekend and thank you !!!
  9. I just stumbled upon it as I was indspensable for my project. Please - have a look at the little but important "correction" of the original code posted by one of the commentators (about NULL values). Rgs,
  10. BINGO - RENDER PARTIAL IS THE CLUE !!! Thank you, Larry !
  11. Hmm, Antonio - please, try to think about this as "tabbed forms" rather than "tabbed content". Then you perhaps can give me a clue how specific tab can communicate with specific controller/model while being served by a single view. This is my problem actually.
  12. Larry, I strongly believe you can add this to your book: http://www.yiiframework.com/extension/unique-attributes-validator/
  13. Hehe - plain language but I fully agree, Larry. Nevertheless - thanks for example but still the main problem remains: - it is NOT how to SHOW things in tabbed manner - it IS how tabbed content should INTERACT with various controllers/models behind (eg. tab 1 relates to controller A while tab 2 relates to controller B.) Any idea here - I would really appreciate!
  14. Thank you, Antonio - a bit too general opinion this time (like how to integrate different tabs with different models/controllers?) but anyway...
  15. Hi, I started to think about dynamic tabbed UI for my application. A dynamic tabbed UI is nice way to present data as they flow during processing. For instance an account is starting a new mailing campaing feeding appropriate data like customer, distribution list, start date, end date, repetition count, etc. When this is completed, a new tab is opened where a designer can feed a mail layout. When this is completed a new tab is opened where customer can drop his/her remarks or approve campaing for mailing. And the beauty of tabbed interface is that all data are nicely layouted and immediately available with no extra server requests. So, this all looks great but I have no idea how this could be implemented with Yii. There is a nice DOJO wrapper for Yii but its documentation is poor and examples available none. Do you have any experience with this sort of interfaces and can share some basic ideas? Larry - why not extend Yii book with some appendix with such a Web 2.0 examples? Please notice - Yii is addvertsed as "best for Web 2.0" whlle it is really hard to find any real "Web 2.0" examples!
  16. Yes, this way of construction CSort objects is documented but actually I believe the problem is deeper and missing support for virtual attributes within CActiveRecord->hasAttribute() method may in fact affect virtual attributes usage in a more complex way. Anyway - I have no time to spent on this any more. I am in serious delay already!
  17. Here you are - I made a bug report: https://github.com/y...yii/issues/1899 Nevertheless, the workin solution is: return new CActiveDataProvider($this, array( 'criteria'=>$criteria, 'pagination'=>array('pageSize'=>10), 'sort' => array( 'attributes'=>array( 'fullname'=>array( 'asc'=>'CONCAT(surname, forename) ASC', 'desc'=>'CONCAT(surname, forename) DESC', ), '*', ), 'defaultOrder' => 'fullname ASC', ), ));
  18. Hmm, I must say it is a bit disappointing to see entire "virtual attribute" concept mostly misleading. Well, I have this inside my 'Users' model: public $fullname; {other code here - not really important} public function search() { $sort = new CSort(); $sort->attributes = array('*', 'CONCAT(surname, ", ", forename) AS fullname'); $sort->defaultOrder = array('fullname' => CSort::SORT_ASC); $criteria=new CDbCriteria; $criteria->select = array('*', 'CONCAT(surname, ", ", forename) AS fullname'); $criteria->compare('id', $this->id); $criteria->compare('login', $this->login, true); $criteria->compare('surname', $this->surname, true); $criteria->compare('forename', $this->forename, true); $criteria->compare('email', $this->email, true); $criteria->compare('CONCAT(surname, ", ", forename)', $this->fullname, true); $criteria->compare('company_id', $this->company_id); $criteria->compare('grupa', $this->grupa); $criteria->compare('active', $this->active); return new CActiveDataProvider($this, array( 'criteria'=>$criteria, 'pagination'=>array('pageSize'=>10), 'sort' => $sort, )); } Having this I have a nice working CGridView and Advanced Search pane but for whatever reason "fullname" column is not sortable. Any idea??? - I feel already exhausted fighting with this all alone...
  19. I strongly encurage you, Larry, to consider this article: http://www.yiiframework.com/wiki/425 as a starting point for implementing a user autentication scheme for an Yii application while writting a respected chapter of your Yii Book. Rgs,
  20. I bet this is the uppercase issue :-)
  21. Hmm, This looks like a bug actually but you may be more clever than myself: presuming we have a form: <div class="form"> <?php $form=$this->beginWidget('CActiveForm', array( 'id'=>'users-form', 'enableClientValidation'=>true, 'clientOptions' => array( 'validateonsubmit'=>true, 'validateonchange'=>true, 'validateOnType'=>false, ), )); ?> <div class="row"> <?php echo $form->labelEx($model, 'active'); ?> <?php echo $form->checkBox($model, 'active', array('uncheckValue'=>0)); ?> <?php echo $form->error($model,'active'); ?> </div> Having client-side validation enabled this way it is imposible to uncheck the 'active' checkbox in case: array('active', 'required', 'message'=>'{attribute} cannot be null !') in a model validation rules. This looks like a discrepancy as the class documentation reads clear: A special option named 'uncheckValue' is available that can be used to specify the value returned when the checkbox is not checked. By default, this value is '0'. Internally, a hidden field is rendered so that when the checkbox is not checked, we can still obtain the posted uncheck value. If 'uncheckValue' is set as NULL, the hidden field will not be rendered. And this is working actually in case a form is submitted having client validation switched off. But it seems client validation javascript is unaware of this documentation!
  22. Hmm - so... what is your question actually? I can't see any.
  23. Ensure you script according Yii conventions. Check class file names are capitalized properly etc.
  24. And if you find some time you could look how to use virtual attributes in search criteria. My solution is based on pure SQL query passed to the database. And is less general than using true virtual attributes expressed in PHP. There must be some trick to do so. In fact, search criteria do not anything more but "translate" some conventional code into a proper SQL query. This is why using virtual attribute in a "naive" way fails: there is no database column reflecting a virtual attribute. So, to overcome the issue sort of filter is necessary where appropriate abstracton should occure. A virtual database column must be assembled on the fly while executing a search query. I am reading this article for instance: http://www.yiiframework.com/wiki/117/using-standard-filters-in-cgridview-custom-fields/ it looks like the good one - isn't it?
  25. I am writting sort of mailing campaigns manager for an addvertising agency. You know - an account starts a campaing, designer uploads his or her creation, customer can review and add his/her comments, these are in the campaing log. They feed the system with an e-mail address list, etc. Lot of functionality. I am short in time already but hopefully it will speed-up soon. Delay was due to my 5-years old daughter got cold and was staying home nearly two weeks. I work at home, and it is impossible to get focus on work while you have such little girl everywhere around trying to pick you up for playing games all the time :-) So really - your comments are helping me a lot in attacking problems. Thank you, Antonio - this is really very kind of you.
  • Create New...