Jump to content
Larry Ullman's Book Forums

ronallensmith

Members
  • Posts

    28
  • Joined

  • Last visited

  • Days Won

    2

Everything posted by ronallensmith

  1. Looks like that's the one!! Yea!! I was actually using Yii::app()->user->name == 'admin' about a week ago, but it didn't work because I didn't kow the correct syntax, and it was erroring out so I abandoned it. The key was the "", the === and the ternary. I can't find this anywhere I was looking. Thanks Edward. Here's the whole thing as intended: array( 'class'=>'CButtonColumn', 'buttons'=>array ( 'delete'=>array ( 'visible'=>"(Yii::app()->user->name==='admin') ? true : false;", ), 'update'=>array ( 'visible'=>"(Yii::app()->user->name==='admin') ? true : false;", ) ) ), Now, any authenticated user, other than admin will only see a "View" button--admin sees "View", "Update" and "Delete". I can retire this project now. Thanks again.
  2. I played around with this for some time and couldn't get it to work properly. It removes "Delete" button for both authenticated users: array( 'class'=>'CButtonColumn', 'buttons'=>array ( 'delete'=>array ( 'visible'=>"(Yii::app()->user->checkAccess('demo')) ? true : false;", ) ) ), My access rules are: public function accessRules() { return array( array('allow', // allow all users to perform 'index' and 'view' actions 'actions'=>array('index','view'), 'users'=>array('*'), ), array('deny', // can't create, update, delete 'actions'=>array('create','update','delete'), 'users'=>array('demo'), ), array('allow', // can create, update, delete 'actions'=>array('create','update','delete'), 'users'=>array('admin'), ), array('allow', // can access CGridView 'actions'=>array('admin'), 'users'=>array('admin','demo'), ), array('deny', // deny all users 'users'=>array('*'), ), ); } So, the CGridView shows for both users, which is what I want, but the "Delete" button doesn't appear for both users which is what I don't want. The good thing though is that I'm not getting errors with this code. I'll keep working with what you gave me though.
  3. The full code for admin.php is: <?php /* @var $this TblContactsController */ /* @var $model TblContacts */ $this->breadcrumbs=array( 'Tbl Contacts'=>array('index'), 'Manage', ); $this->menu=array( array('label'=>'List TblContacts', 'url'=>array('index')), array('label'=>'Create TblContacts', 'url'=>array('create')), ); Yii::app()->clientScript->registerScript('search', " $('.search-button').click(function(){ $('.search-form').toggle(); return false; }); $('.search-form form').submit(function(){ $('#tbl-contacts-grid').yiiGridView('update', { data: $(this).serialize() }); return false; }); "); ?> <h1>Manage Tbl Contacts</h1> <p> You may optionally enter a comparison operator (<b><</b>, <b><=</b>, <b>></b>, <b>>=</b>, <b><></b> or <b>=</b>) at the beginning of each of your search values to specify how the comparison should be done. </p> <?php echo CHtml::link('Advanced Search','#',array('class'=>'search-button')); ?> <div class="search-form" style="display:none"> <?php $this->renderPartial('_search',array( 'model'=>$model, )); ?> </div><!-- search-form --> <?php $this->widget('zii.widgets.grid.CGridView', array( 'id'=>'tbl-contacts-grid', 'dataProvider'=>$model->search(), 'filter'=>$model, 'columns'=>array( 'id', 'contactType', 'startTime', 'endTime', 'duration', 'site', /* 'prefix', 'firstName', 'lastName', 'suffix', 'phone1', 'ext1', 'phone2', 'ext2', 'email', 'subject', 'notes', 'followUp', */ array( 'class'=>'CButtonColumn', 'buttons'=>array ( 'delete' => array ( 'label'=>'Delete', //other params 'visible'=>!Yii::app()->user->checkAccess('admin'), ), ), ), ), )); ?>
  4. Thanks Larry, The error follows below and was generated when using the code mentioned in post# 14 above: # /protected/views/MyModel/admin.php array( 'class'=>'CButtonColumn', 'buttons'=>array ( 'delete' => array ( 'label'=>'Delete', //other params 'visible'=>!Yii::app()->user->checkAccess('admin'), ), ), ), ), )); ?> The complete error is: PHP warningcall_user_func_array() expects parameter 1 to be a valid callback, no array or string given C:\wamp\framework\base\CComponent.php(611) 599 * @since 1.1.0600 */601 public function evaluateExpression($_expression_,$_data_=array())602 {603 if(is_string($_expression_))604 {605 extract($_data_);606 return eval('return '.$_expression_.';');607 }608 else609 {610 $_data_[]=$this;611 return call_user_func_array($_expression_, $_data_);612 }613 }614 }615 616 617 /**618 * CEvent is the base class for all event classes.619 *620 * It encapsulates the parameters associated with an event.621 * The {@link sender} property describes who raises the event.622 * And the {@link handled} property indicates if the event is handled.623 * If an event handler sets {@link handled} to true, those handlers Stack Trace #0 + C:\wamp\framework\base\CComponent.php(611): call_user_func_array(true, array("row" => 0, "data" => TblContacts, 0 => CButtonColumn)) #1 + C:\wamp\framework\zii\widgets\grid\CButtonColumn.php(313): CComponent->evaluateExpression(true, array("row" => 0, "data" => TblContacts)) #2 + C:\wamp\framework\zii\widgets\grid\CButtonColumn.php(295): CButtonColumn->renderButton("delete", array("label" => "Delete", "url" => "Yii::app()->controller->createUrl("delete",array("id"=>$data->pr...", "imageUrl" => "/calls/assets/a6e77b09/gridview/delete.png", "options" => array("class" => "delete"), ...), 0, TblContacts) #3 + C:\wamp\framework\zii\widgets\grid\CGridColumn.php(144): CButtonColumn->renderDataCellContent(0, TblContacts) #4 + C:\wamp\framework\zii\widgets\grid\CGridView.php(589): CGridColumn->renderDataCell(0) #5 + C:\wamp\framework\zii\widgets\grid\CGridView.php(545): CGridView->renderTableRow(0) #6 + C:\wamp\framework\zii\widgets\grid\CGridView.php(455): CGridView->renderTableBody() #7 + C:\wamp\framework\zii\widgets\CBaseListView.php(160): CGridView->renderItems() #8 unknown(0): CBaseListView->renderSection(array("{items}", "items")) #9 + C:\wamp\framework\zii\widgets\CBaseListView.php(143): preg_replace_callback("/{(\w+)}/", array(CGridView, "renderSection"), "{summary} {items} {pager}") #10 + C:\wamp\framework\zii\widgets\CBaseListView.php(128): CBaseListView->renderContent() #11 + C:\wamp\framework\web\CBaseController.php(173): CBaseListView->run() #12 – C:\wamp\www\calls\protected\views\tblContacts\admin.php(88): CBaseController->widget("zii.widgets.grid.CGridView", array("id" => "tbl-contacts-grid", "dataProvider" => CActiveDataProvider, "filter" => TblContacts, "columns" => array("id", "contactType", "startTime", "endTime", ...))) 83 'visible'=>!Yii::app()->user->checkAccess('admin'),84 ),85 ),86 ),87 ),88 )); ?> #13 + C:\wamp\framework\web\CBaseController.php(126): require("C:\wamp\www\calls\protected\views\tblContacts\admin.php") #14 + C:\wamp\framework\web\CBaseController.php(95): CBaseController->renderInternal("C:\wamp\www\calls\protected\views\tblcontacts\admin.php", array("model" => TblContacts), true) #15 + C:\wamp\framework\web\CController.php(869): CBaseController->renderFile("C:\wamp\www\calls\protected\views\tblcontacts\admin.php", array("model" => TblContacts), true) #16 + C:\wamp\framework\web\CController.php(782): CController->renderPartial("admin", array("model" => TblContacts), true) #17 – C:\wamp\www\calls\protected\controllers\TblContactsController.php(147): CController->render("admin", array("model" => TblContacts)) 142 if(isset($_GET['TblContacts']))143 $model->attributes=$_GET['TblContacts'];144 145 $this->render('admin',array(146 'model'=>$model,147 ));148 }149 150 /**151 * Returns the data model based on the primary key given in the GET variable.152 * If the data model is not found, an HTTP exception will be raised. #18 + C:\wamp\framework\web\actions\CInlineAction.php(49): TblContactsController->actionAdmin() #19 + C:\wamp\framework\web\CController.php(308): CInlineAction->runWithParams(array()) #20 + C:\wamp\framework\web\filters\CFilterChain.php(133): CController->runAction(CInlineAction) #21 + C:\wamp\framework\web\filters\CFilter.php(40): CFilterChain->run() #22 + C:\wamp\framework\web\CController.php(1145): CFilter->filter(CFilterChain) #23 + C:\wamp\framework\web\filters\CInlineFilter.php(58): CController->filterAccessControl(CFilterChain) #24 + C:\wamp\framework\web\filters\CFilterChain.php(130): CInlineFilter->filter(CFilterChain) #25 + C:\wamp\framework\web\CController.php(291): CFilterChain->run() #26 + C:\wamp\framework\web\CController.php(265): CController->runActionWithFilters(CInlineAction, array("accessControl", "postOnly + delete")) #27 + C:\wamp\framework\web\CWebApplication.php(282): CController->run("admin") #28 + C:\wamp\framework\web\CWebApplication.php(141): CWebApplication->runController("tblcontacts/admin") #29 + C:\wamp\framework\base\CApplication.php(169): CWebApplication->processRequest() #30 – C:\wamp\www\calls\index.php(13): CApplication->run() 08 defined('YII_DEBUG') or define('YII_DEBUG',true);09 // specify how many levels of call stack should be shown in each log message10 defined('YII_TRACE_LEVEL') or define('YII_TRACE_LEVEL',3);11 12 require_once($yii);13 Yii::createWebApplication($config)->run(); 2013-10-05 03:12:50 Apache/2.4.4 (Win32) PHP/5.4.16 Yii Framework/1.1.13
  5. Hmm, based on http://stackoverflow...l-delete-button and http://www.yiiframework.com/doc/api/CButtonColumn, I used # /protected/views/MyModel/admin.php array( 'class'=>'CButtonColumn', 'buttons'=>array ( 'delete'=>array ( 'label'=>'Delete', 'visible'=>!Yii::app()->user->checkAccess('guest'), ), ), ), But, get php error message saying: call_user_func_array() expects parameter 1 to be a valid callback, no array or string given
  6. Thanks Edward and Larry. Sorry I stepped away from the problem for a day to handle other issues. I'm taking a look at your response Edward; give me a liitle time to give any feedback. Hey, Larry! I've gotten better at knowing where to look regarding solving Yii related problems, and in my opinion the Yii Book and the Yii framework Class Reference docs have yielded the most frequent hints and solutions. Thanks I'm very gratefull for your help.
  7. Thanks Edward, I reeeaaallly appreciate your help. Concerning your first suggestion "...just direct admin or the user to the same CGridView..." When you say "...just disable its attributes depending on the user.", are you meaning to do so in /protected/controllers/MyModelController.php, public function accessRules(), or somewhere else?? Here's where I'd like to have users, other than admin, only have the "View" button displayed; all 3 default buttons displayed for admin, of course. I took a look around and can't find anything on how to do this using just one "CGridView"--unless I'm overlooking something. That's when I thought of creating 2 admin views, but that's also when I become veeery confused, Haha. It seems to me this should be done in the controller, but then how do you do it? It just dawns on me to maybe create another action something like 'public function actionGuest()' in the Model controller, then have '$this->redirect(Yii::app()->user->returnUrl=array('tblContacts/guest'));' in the Site controller. Now the problem is how to remove the Update and Delete buttons. Sorry for so many words.
  8. The following seems to work for redirecting to two different views based on identity of user, but I'd like someone to check it's validity and best practices, since I'm a newbie: # protected/controllers/SiteController.php public function actionLogin() { $model=new LoginForm; // if it is ajax validation request if(isset($_POST['ajax']) && $_POST['ajax']==='login-form') { echo CActiveForm::validate($model); Yii::app()->end(); } // collect user input data if(isset($_POST['LoginForm'])) { $model->attributes=$_POST['LoginForm']; // validate user input and redirect to the specified page if valid if($model->validate() && $model->login() && Yii::app()->user->name == 'admin') { $this->redirect(Yii::app()->user->returnUrl=array('MyModelController/admin')); } else { $this->redirect(Yii::app()->user->returnUrl=array('MyModelController/index')); } } // display the login form $this->render('login',array('model'=>$model)); } How's this? Now the only thing left is to have the else{} clause redirect to a cloned admin view without the Delete and Update buttons, instead of index, as in this test. Can Gii be used to generate the other view, or whatever? Anyone have any hints?
  9. SOLVED: KonApaz in the Yii Framework Forum suggested: #/protected/controllers/SiteController::actionLogin() $this->redirect(Yii::app()->user->returnUrl=array('controller/action')); This works beautifully, unless someone has a better (best practices) way.
  10. In the Yii Book in the section "Handling Redirections" it talks about $this->redirect(Yii::app()->user->returnUrl);. However, in my opinion, for the beginner, there could be more info on how to redirect to a different page/view upon a successful login. In my case I need to redirect to /protected/views/myModel/admin.php. This was completely skipped over in the material. What would I replace Yii::app()->user->returnUrl with in my case??
  11. I just had a thought while researching the above. Could it be that, using the code you suggest above, I just copy and rename the .../protected/views/MyModel/admin.php file to something like '.../protected/views/MyModel/guest.php' in order to make the second view for the 'guest' user? Then edit the 'CButtonColumn' Class in guest.php to remove the 'update' and 'delete' buttons?
  12. Thanks Edward, Do I create the two separate views with the Gii tool; when I went to do that it looked like a totally separate Controller would be created? And, this is a very simple site where I only have the 2 users 'admin' and 'guest'. So, will the 'Yii::app()->user->type === ...' work with the following: class UserIdentity extends CUserIdentity { /** * Authenticates a user. * The example implementation makes sure if the username and password * are both 'demo'. * In practical applications, this should be changed to authenticate * against some persistent user identity storage (e.g. database). * @return boolean whether authentication succeeds. */ public function authenticate() { $users=array( // username => password // 'demo'=>'demopassword', 'admin'=>'adminpassword', 'guest'=>'guestpassword', ); if(!isset($users[$this->username])) $this->errorCode=self::ERROR_USERNAME_INVALID; elseif($users[$this->username]!==$this->password) $this->errorCode=self::ERROR_PASSWORD_INVALID; else $this->errorCode=self::ERROR_NONE; return !$this->errorCode; } }
  13. I'm looking through the book, but getting turned around on the concept of redirecting authenticated users to custom views. Is it that I create another Model and Controller with the Gii tool to create a custom view, or can that be done using the existing Model's Controller?? I'm using the following Access Rules: public function accessRules() { return array( array('deny', // deny guest to perform 'create', 'update' and 'delete' actions 'actions'=>array('create','update','delete'), 'users'=>array('guest'), ), array('allow', // allow authenticated user to perform 'create' and 'update' actions 'actions'=>array('create','update'), 'users'=>array('admin'), ), array('allow', // allow admin user to perform 'admin' and 'delete' actions 'actions'=>array('admin','delete'), 'users'=>array('admin'), ), array('allow', // allow all users to perform 'index' and 'view' actions 'actions'=>array('index','view'), 'users'=>array('@'), ), array('deny', // deny all users 'users'=>array('*'), ), array('deny', // deny 'delete' action for all contexts 'actions'=>array('delete'), ), ); } admin is no problem, but I need the guest to redirect to a different GridView than the one admin sees, that only has ability to View and not Update and Delete. The problem is I have to do this manually in the URL so far--even for admin login.
  14. I'm adding a heads-up here! When I uploaded my app, the math on the time changed because the hosting server was in a different timezone. So... Arghh!! I commented-out the 'public function behaviors()' code and changed the 'public function beforeSave()' code to: // added to INSERT "endTime" and "duration" public function beforeSave() { if ($this->isNewRecord) { $this->endTime = date('Y-m-d H:i:s', strtotime('-2 Hours')); // set the endTime $start = new DateTime($this->startTime); $end = new DateTime($this->endTime); $dateIntervalObj = $end->diff($start); // compute the difference in times $this->duration = $dateIntervalObj->format('%H%I%S'); // format and set the difference in time } return parent::beforeSave(); } I hope this helps someone who runs accross the same problem.
  15. A hearty thanks to you Edward for the leads you gave in working on this solution, and if you or Larry have a better more concise/cleaner way of doing the same thing, or a way the same thing could have been done using the Yii classes, please let me know.
  16. SOLVED: The following was added to myModel.php // added to INSERT (endTime - startTime) into "duration" public function beforeSave() { if ($this->isNewRecord) { $start = new DateTime($this->startTime); $end = new DateTime(); $endMinus7 = $end->sub(new DateInterval('PT7H')); // correct for 7-hour time difference $dateIntervalObj = $endMinus7->diff($start); // compute the difference in times $this->duration = $dateIntervalObj->format('%H%I%S'); } return parent::beforeSave(); }
  17. I Just tested the following: // added to INSERT (endTime - startTime) into "duration" public function beforeSave() { if ($this->isNewRecord) { $start = new DateTime($this->startTime); $end = new DateTime(); $dateIntervalObj = $end->diff($start); $this->duration = $dateIntervalObj->format('%H%I%S'); } return parent::beforeSave(); } which yielded the follwing two records on two tests: View TblContacts #210 ID 210 Contact Type Inbound Voice-Message Start Time 2013-09-21 13:17:25 End Time 2013-09-21 13:17:50 Duration 07:00:25 View TblContacts #211 ID 211 Contact Type Inbound Voice-Message Start Time 2013-09-21 13:27:51 End Time 2013-09-21 13:31:18 Duration 07:03:27 As you can see "Duration" is at least being written too. I don't know what the problem was before, because this is essentially the same code I was using before--but wasn't working. I de-selected NULL for "duration", manally cleaned up the table and SET "duration" back to NULL; now the math and INSERTs work. The only thing left is to adjust for the timezone.
  18. Thanks Edward, I took a look at the way the table itself is constructed and went at the problem from the "MySQL command-line" standpoint and discovered I could not manually INSERT the time difference into the "duration" field with: SELECT TIMEDIFF('2013-09-20 13:17:20','2013-09-20 13:08:48'); UPDATE tblcontacts SET duration = '00:08:32' where id = 204; as an example. But, this was only happening for some of the records and not others. So, when I looked at that issue, I noticed for some records, "duration" was NULL after the INSERT--displaying as "Not set" in Yii. All the records that were set this way would not even allow me to do the INSERT manually. So, I de-selected NULL in phpMyAdmin and was able to manually do the INSERTs using the above "SELECT TIMEDIFF()/UPDATE" commads. Here's what's curious now. After manually UPDATEing all the NULL records, I'm able to do the manual INSERTs, from the command-line, even on records that have "duration" set to NULL. So, now I'm back on the Yii side testing your previous suggestions.
  19. Thanks again, The reason for INSERTing the "duration" is because I'll be giving others the ability to login to the site and check the saved records. One item of interest will be "duration"--the time it took for me to complete a task. I'll continue to hammer on the DateTime interval object, but I'll check the others you mentioned.
  20. Thanks for taking the time Edward, I;m now using: // added to INSERT (endTime - startTime) into "duration" public function beforeSave() { if ($this->isNewRecord) { $start = new DateTime($this->startTime); $end = new DateTime(); $diffObj = $end->diff($start); $this->duration = $diffObj->format('%H%I%S'); } return parent::beforeSave(); } and getting: Start Time 2013-09-18 17:31:48 End Time 2013-09-18 17:32:08 Duration 2007-00-20 00:00:00 Looks like something's wrong with the way I'm formatting.
  21. Edward, Your suggestion to revisit using 'beforeSave()' worked also. It's funny because I saw both these approached in the Yii book--DOH! but I went with 'afterSave()' instead. I was all over the web too with this problem. After a while I just got snowed under by an avalanche of info and samples. ...takes fresh eyes some times. Now, I need to replace CDbExpression() with whatever can do (endTime - startTime) and INSERT into "duration". // added to INSERT (endTime - startTime) into "duration, if possible" public function beforeSave() { if ($this->isNewRecord) { $this->duration = new CDbExpression('NOW()'); // This works, but I need to replace it with something like endTime - startTime } return parent::beforeSave(); }
  22. Thanks again. I'll try beforeSave() as well. My table structure as far as "duration" is concerned is: tblcontacts | CREATE TABLE `tblcontacts` ( `id` int(10) unsigned NOT NULL AUTO_INCREM `contactType` enum('Inbound Voice-Message' `startTime` datetime NOT NULL, `endTime` datetime DEFAULT NULL, `duration` datetime NOT NULL,
  23. Thanks Edward, the following worked: array('duration', 'default', 'value'=>new CDbExpression('NOW()'), 'on'=>'insert'), The NOW() call is just a simple test to see if the insert works at all. Now I'll replace that with the math expression that subtracts "startTime" from "endTime"--see above posts marked "SOLVED:". I'm thinking of using MySQL's TIMEDIFF() for the math unless you have a better suggestion using a Yii class. The 'afterSave()' example you gave still did not work and if memory serves me well I tried that one before myself, with the same result--nill. Thanks a bunch. This is a breakthrough ...been trying to solve this one for several days.
  24. Hi Larry, Sure. My app keeps track of what was said during phone calls. It tracks the time the call started and the time it ended. However I'm stuck on how to INSERT the duration of the call. I've worked out the start and end times--shown above, but don't quite know how to implement the afterSave(). I see a few examples, but it seems I'm not experienced enough with Yii yet to put it all together properly. The following code does not produce errors, but it doesn't INSERT the correct values either. I just get 0000-00-00 00:00:00 in the "duration" column. // added to ...protected\models\TblContacts.php to INSERT difference between startTime and endTime protected function afterSave() { return parent::afterSave(); if ($this->isNewRecord) { $this->duration = new CDbExpression('NOW()'); // thinking of using TIMEDIFF() here instead // update(); // update($duration); // $duration->update(); $duration->save(); } }
  25. Thanks for the reply Larry, As you can see, I've solved 66% of my problem. Now I need to insert the difference between the above two timestamps into a field called 'duration' in H:i:s format. I've looked all over the Yii docs and the Forum where I came upon afterSave(), and I bought the Yii Book where afterSave() is mentioned. My problem it that I'm seeing different situations where this is used. I think I'm on the right track, but need the final nail in the coffin regarding this problem. I've tried several variations of the following code, but the following post is the only version not producing an error--but it doesn't do anyrhing either. //added the following to myModel.php protected function afterSave() { parent::afterSave(); if ($this->isNewRecord) { $this->duration = new CDbExpression('NOW()'); } } People have posted me back elsewhere, and I'm still confused on the missing piece. BTW - CDbExpression('NOW()') is just being used to test saving the date. Of course the goal is to include the methods that actually extract the difference in timestamps.
×
×
  • Create New...