Solved

Cake PHP Admin Edit not working

Posted on 2010-09-16
2
680 Views
Last Modified: 2012-05-10
I'm new to Cake, though very comfortable with PHP.

I'm trying to debug a function on the Admin page where an administrator can update a user's password. There are no errors, but the password isn't updating and I have no idea why.

I have the AppController attached thinking there might be some clues there. Any help would be appreciated.
<?php
/**
 * @package eLivestockAuctions
 * @version 1.0
 * @author Scott Stanger <sstanger@highcorral.com>
 * @link http://www.highcorral.com/
 * @filesource
 *
 * Ajax Chat
 * @reference http://bakery.cakephp.org/articles/view/ajax-chat-plugin-using-jquery
 */

/**
 *
 */
class AppController extends Controller {

    /**
     * helpers 
     * 
     * @var string
     * @access public
     */
 	public $helpers = array('Form', 'Html', 'Javascript', 'Ajax', 'Thumbnail', 'Time', 'Session', 'Banner');
    /**
     * components 
     * 
     * @var string
     * @access public
     */
	public $components = array('FileUpload.FileUpload', 'Auth', 'Cookie', 'Email', 'RequestHandler', 'Session');
    /**
     * pageTitle 
     *
	 * provides default page title in case custom is not created within controller
     * 
     * @var string
     * @access public
     */
	public $pageTitle = 'eLivestockAuctions';
    /**
     * selectedMenu 
     *
	 * which main menu item is selected
     * 
     * @var string
     * @access public
     */
	public $selectedMenu = 'home';

    /**
     * beforeFilter
     * 
     * Application hook which runs prior to each controller action
     * 
     * @access public 
     */
    public function beforeFilter()
	{
		// If called via cron or command line then check for the dispatcher constant
		if (defined('CRON_DISPATCHER'))
		{
			return;
		}
	
		// Set up Auth Component
		// http://tomscrape.com/node/18
		$this->Auth->loginAction = array('admin' => false, 'controller' => 'users', 'action' => 'login');
#		$this->Auth->allow(array('*'));	// move this to individual controllers

		// Controller autorization is the simplest form.
		$this->Auth->authorize = 'controller';

		//  Additional criteria for logging in.
		$this->Auth->userScope = array(
			'User.active' 	=> 1,	// user needs to be active (0 indicates they have been deleted).
		); 
		
		$this->Auth->autoRedirect = false;
		$this->Auth->fields = array('username' => 'email', 'password' => 'password');

		
		// See if a user is logged in via cookie
		$this->checkLogin();

        // ----------------------------------------------------------------------------------------------------
        // ---------------------------------------------------------------------------------------------------(
        // Check to make sure that a logged in user has not been "deleted"...
        //   ... if they are, log them out!
        //
            $user = $this->Auth->user();

            $this->loadModel('User');
            $this->User->id = $user['User']['id'];
            $this->User->contain();
            $u = $this->User->read(array('id', 'active'));

            if (Set::check($u, 'User.active') && $u['User']['active'] == 0) {
                $this->Cookie->delete('Auth.User');
                $this->Auth->logout();
                return $this->redirect(array('controller'=>'users', 'action'=>'login'));
            }
        //
        // )---------------------------------------------------------------------------------------------------
        // ----------------------------------------------------------------------------------------------------

		// Check the session to see if there is a logged in user
		$loggedInUser = $user;

		$this->set('loggedInUser', $loggedInUser);
        $this->loggedInUser = $loggedInUser;

        if (@$this->params['admin'])
            $this->layout = 'admin';
			
		// Bookkeeping
		// Delete ads that have expired
		$this->expireClassifiedAds();
		
		$this->loadConfig();
		
    }

	/**
	 * See if a user is logged in via cookie and return the User or false
	 *
	 * @return boolean
	 */
	public function checkLogin()
	{
		$cookie = $this->Cookie->read('Auth.User');
		if (!is_null($cookie)) 
		{
			if ($this->Auth->login($cookie) === true)
			{
				//  Clear auth message, just in case we use it.
				$this->Session->del('Message.auth');
				return true;
			} 
			else 
			{ 
				// Delete invalid Cookie
				$this->Cookie->del('Auth.User');
			}
		}
		return false;
	}

	/**
	 * See if the logged in user is an admin.
	 *
	 * return boolean
	 */
	public function checkAdminSession()
	{
		$loggedInUser = $this->Auth->user();
		return ($loggedInUser['User']['group_id'] == 1)?true:false;
	} // checkAdminSession()
	
	/**
	 * Before render
	 */
	public function beforeRender()
	{
		$this->set('selectedMenu', $this->selectedMenu);
		$this->set('title_for_layout', $this->pageTitle);
	}
	
	/**
	 * Send the Contact Email to the admins
	 *
	 * @param array
	 */
	public function sendContactEmail($data) 
	{
		$options = array(
			'to'		=> array('Scott W. Stanger <sstanger@highcorral.com>'),
			'subject'	=> 'Contact Request',
			'layout'	=> 'system',
			'template'	=> 'contact',
		);
		
		// Set view variables which will be available to the email template
		$data['subject'] 		= $options['subject'];

		$this->sendEmail($options, $data);
	
	}
	
	/**
	 * Load the config options from the database
	 */
	public function loadConfig()
	{
		$this->loadModel('Option');
		$this->Option->id = 1;
		$emailStuff = $this->Option->read();
	
		if (empty($emailStuff['Option']['fromEmail']))
		{
			$fromEmail = 'no-reply@highcorral.com';
		}
		else
		{
			if (empty($emailStuff['Option']['fromName']))
			{
				$fromEmail = $emailStuff['Option']['fromEmail'];
			}
			else
			{
				$fromEmail = $emailStuff['Option']['fromName'] . ' <' . $emailStuff['Option']['fromEmail'].'>';
			}
		}
	
		
		Configure::write('fromEmail'	, $fromEmail);
		Configure::write('smtpEnabled'	, $emailStuff['Option']['smtpEnabled']);
		Configure::write('smtpHost'		, $emailStuff['Option']['smtpHost']);
		Configure::write('smtpUsername'	, $emailStuff['Option']['smtpUsername']);
		Configure::write('smtpPassword'	, $emailStuff['Option']['smtpPassword']);
	
	} // loadConfig()

    /**
	  * Send an email
	  * @see http://book.cakephp.org/view/176/Email
	  *
	  * @param array $options Email options
	  * @param array $tvars Template Variables
	  */	
	function sendEmail($options, $data)
	{

		$data['ipaddress'        ]  = empty($_SERVER['REMOTE_ADDR'])?'no ip (cron job)':$_SERVER['REMOTE_ADDR'];
		$data['dateTime'         ]  = date('Y-m-d h:i:s');
		$data['website'          ]  = 'http://www.elivestockauction.com';
		$data['supportSignature' ]  = 'eLivestockAuction';
		
		$this->set('emailData', $data);

		// Set up some defaults
		$options['from'] = Configure::read('fromEmail');
		
		if (empty($options['sendAs']))	$options['sendAs'] 	= 'text';		// 'html' | 'text' | 'both'
			

		// The default delivery is via 'mail'.  To use SMTP, uncomment the following
		// line and be sure to fill in the smtpOptions array
		if (Configure::read('smtpEnabled'))
		{
			$this->Email->delivery = 'smtp';

			/* SMTP Options (only used if delivery type is set to 'smtp' */
			$this->Email->smtpOptions = array(
				'port'		=>'25', 
				'timeout'	=>'30',
				'host' 		=>Configure::read('smtpHost'),
				'username'	=>Configure::read('smtpUsername'),
				'password'	=>Configure::read('smtpPassword')
			);
		}
		
		foreach ($options['to'] as $to)
		{
			// The 'to' member must be a string -- not an array
			$this->Email->to = $to;

			foreach ($options as $key => $value)
			{
				switch ($key)
				{
					case 'cc'       : $this->Email->cc       = $value; break;
					case 'bcc'      : $this->Email->bcc      = $value; break;
					case 'subject'  : $this->Email->subject  = $value; break;
					case 'replyTo'  : $this->Email->replyTo  = $value; break;
					case 'from'     : $this->Email->from     = $value; break;
					case 'template' : $this->Email->template = $value; break;
					case 'sendAs'   : $this->Email->sendAs   = $value; break;
					case 'layout'   : $this->Email->layout   = $value; break; // views/layouts/email/{html|text}/default.thtml or whatever wrapper you want to use
				}
			}

#pr($this->Email); exit;
			if (!$this->Email->send())
			{
				#print 'Email error: ' . $this->Email->smtpError;
				#exit;
			}
			$this->Email->reset();
		}
		
	} // sendEmail()
	

    /**
     * isAuthorized 
     * 
     * @access public
     * @return void
     */
    public function isAuthorized() {

        //TODO : What is this function for??
        return true;
    }


    /**
     * page 
     *
     * is a convenience function for setting up pagination
     * 
     * @param string $model 
     * @param string $sortCol 
     * @param array $conditions 
     * @param array $mergeData 
     * @param string $sortDir 
     * @param integer $limit 
     * @param boolean $useModelInOrder
     * @param boolean $fixPaginateCount
     * @access protected
     * @return void
     */
    protected function page($model, $sortCol='name', $conditions=array(), $mergeData=array(), $sortDir='ASC', $limit=10, $useModelInOrder=true, $fixPaginateCount=false)
    {
        $this->loadModel($model);

        $this->paginate[$model] = array(
            'limit' => $limit,
        );

        if ((bool)$useModelInOrder)
             $this->paginate[$model]['order'] = array("$model.`$sortCol`" => $sortDir);
        else $this->paginate[$model]['order'] = array("`$sortCol`" => $sortDir);

        if (!empty($mergeData))
            $this->paginate[$model] = array_merge($this->paginate[$model], $mergeData);

        if ($fixPaginateCount)
            $this->$model->multiJoinPaginate = true;

        $stuff = $this->paginate($model, $conditions);
        $this->set(Inflector::pluralize(strtolower($model)), $stuff);

        return $stuff;
    }

    /**
     * getFilterData
     *
     * gets and sets session data for data set filters
     *
     * @access protected
     * @param string $filterKey
     * @return void
     */
    protected function getFilterData($filterKey)
    {
        if (isset($this->passedArgs['filters']) && $this->passedArgs['filters'] == 'clear')
            $this->Session->write("{$filterKey}FilterData"); // Clear out the Filter Data

        $filterData = $this->Session->read("{$filterKey}FilterData");
        if ((isset($this->data) && isset($this->data['Filters'])) || isset($filterData['Filters'])) {

            // A current filter request trumps whatever is in the Session ...
            $filterData = (Set::check($this->data, 'Filters') && !empty($this->data['Filters'])) ? $this->data['Filters'] : $filterData['Filters'] ;

            // ... and then it gets written to the Session
            $this->Session->write("{$filterKey}FilterData", array('Filters' => $filterData));
        }
        
        if (!empty($filterData) && is_array($filterData)) {

            // So that it will show up in the form...
            //  (that is, if the current action doesn't
            //   override this by just setting $this->data)
            $this->data['Filters'] = $filterData;

            $this->set('isFilterSet', true);
            return $filterData;
        }

        $this->set('isFilterSet', false);
        return false;
    }


    /**
     * clearUnwantedUploads 
     *
     * for dealing with uploads that were auto uploaded by the FileUpload component
     *
     * Before using this function, it may be wise to make sure that
     * the FileUpload component is loaded into the appropriate Controller
     * 
     * @access protected
     * @return void
     */
    protected function clearUnwantedUploads()
    {
        foreach ($this->FileUpload->finalFiles as $finalFile)
        {
            $this->FileUpload->removeFile($finalFile);
            $this->Upload->contain();
            $upload = $this->Upload->findByName($finalFile);
            $this->Upload->delete($upload['Upload']['id']);
        }
    }
	
    /**
     * buildFilterConditions
     *
     * $filterFieldArr should be an array of the following format:
     *
     *      $filterFieldArr = array(
     *          '<Model>' => array(
     *              'int|int_lt|int_gt|int_lt_gt|float|float_lt|float_gt|float_lt_gt|string|string_exactly|date' => array(
     *                  '<filteElementKey>' => '<dbField>', // OR: '<dbField>' (if <dbField> and <filteElementKey> are the same)
     *              ),
     *              // ...
     *          ),
     *          // ...
     *      );
     *
     *      where <filteElementKey> is the key of the array passed in from the web form
     *        and <dbField> is, well, the database field name
     * 
     * @param array $filterData
     * @param array $filterFieldArr
     * @access protected
     * @return void
     */
    protected function buildFilterConditions($filterData, $filterFieldArr) {

        $conditions = array();


        foreach ($filterFieldArr as $modelName => $filterFields) {

            // ----------------------------------------------------------------------------------------------------------------------------------------------------------
            // ---------------------------------------------------------------------------------------------------------------------------------------------------------(
            // Integers
            //
                // INTEGERS
                if (Set::check($filterFields, 'int') && !empty($filterFields['int'])) {

                    foreach ($filterFields['int'] as $key => $field) {
                        if (is_numeric($key))
                            $key = $field;

                        if (!empty($filterData[$key]))
                            $conditions["$modelName.`$field`"] = (int)$filterData[$key];
                    }
                }

                // INTEGERS LT
                if (Set::check($filterFields, 'int_lt') && !empty($filterFields['int_lt'])) {

                    foreach ($filterFields['int_lt'] as $key => $field) {
                        if (is_numeric($key))
                            $key = $field;

                        if (!empty($filterData[$key]))
                            $conditions["$modelName.`$field` <"] = (int)$filterData[$key];
                    }
                }

                // INTEGERS GT
                if (Set::check($filterFields, 'int_gt') && !empty($filterFields['int_gt'])) {

                    foreach ($filterFields['int_gt'] as $key => $field) {
                        if (is_numeric($key))
                            $key = $field;

                        if (!empty($filterData[$key]))
                            $conditions["$modelName.`$field` >"] = (int)$filterData[$key];
                    }
                }

                // INTEGERS with LT and GT
                if (Set::check($filterFields, 'int_lt_gt') && !empty($filterFields['int_lt_gt'])) {

                    foreach ($filterFields['int_lt_gt'] as $key => $field) {
                        if (is_numeric($key))
                            $key = $field;

                        if (!empty($filterData[$key       ])) $conditions["$modelName.`$field`"  ] = (int)str_replace(array(',', '$'), '', $filterData[$key       ]);
                        if (!empty($filterData["{$key}_lt"])) $conditions["$modelName.`$field` <"] = (int)str_replace(array(',', '$'), '', $filterData["{$key}_lt"]);
                        if (!empty($filterData["{$key}_gt"])) $conditions["$modelName.`$field` >"] = (int)str_replace(array(',', '$'), '', $filterData["{$key}_gt"]);
                    }
                }
            //
            // )---------------------------------------------------------------------------------------------------------------------------------------------------------
            // ----------------------------------------------------------------------------------------------------------------------------------------------------------


            // ----------------------------------------------------------------------------------------------------------------------------------------------------------
            // ---------------------------------------------------------------------------------------------------------------------------------------------------------(
            // Floats
            //
                // FLOATS
                if (Set::check($filterFields, 'float') && !empty($filterFields['float'])) {
                    foreach ($filterFields['float'] as $key => $field) {
                        if (is_numeric($key))
                            $key = $field;

                        if (!empty($filterData[$key]))
                            $conditions["$modelName.`$field`"] = (float)str_replace(array(',', '$'), '', $filterData[$key]);
                    }
                }

                // FLOATS LT
                if (Set::check($filterFields, 'float_lt') && !empty($filterFields['float_lt'])) {
                    foreach ($filterFields['float_lt'] as $key => $field) {
                        if (is_numeric($key))
                            $key = $field;

                        if (!empty($filterData[$key]))
                            $conditions["$modelName.`$field` <"] = (float)str_replace(array(',', '$'), '', $filterData[$key]);
                    }
                }

                // FLOATS GT
                if (Set::check($filterFields, 'float_gt') && !empty($filterFields['float_gt'])) {
                    foreach ($filterFields['float_gt'] as $key => $field) {
                        if (is_numeric($key))
                            $key = $field;

                        if (!empty($filterData[$key]))
                            $conditions["$modelName.`$field` >"] = (float)str_replace(array(',', '$'), '', $filterData[$key]);
                    }
                }

                // FLOATS LT and GT
                if (Set::check($filterFields, 'float_lt_gt') && !empty($filterFields['float_lt_gt'])) {
                    foreach ($filterFields['float_lt_gt'] as $key => $field) {
                        if (is_numeric($key))
                            $key = $field;

                        if (!empty($filterData[$key       ])) $conditions["$modelName.`$field`"  ] = (float)str_replace(array(',', '$'), '', $filterData[$key       ]);
                        if (!empty($filterData["{$key}_lt"])) $conditions["$modelName.`$field` <"] = (float)str_replace(array(',', '$'), '', $filterData["{$key}_lt"]);
                        if (!empty($filterData["{$key}_gt"])) $conditions["$modelName.`$field` >"] = (float)str_replace(array(',', '$'), '', $filterData["{$key}_gt"]);
                    }
                }
            //
            // )---------------------------------------------------------------------------------------------------------------------------------------------------------
            // ----------------------------------------------------------------------------------------------------------------------------------------------------------


            // ----------------------------------------------------------------------------------------------------
            // ---------------------------------------------------------------------------------------------------(
            // Strings
            //
                // STRINGS
                if (Set::check($filterFields, 'string') && !empty($filterFields['string'])) {
                    foreach ($filterFields['string'] as $key => $field) {
                        if (is_numeric($key))
                            $key = $field;

                        if (!empty($filterData[$key]))
                            $conditions["$modelName.`$field` LIKE"] = '%'.$this->sanit($filterData[$key]).'%';
                    }
                }

                // STRINGS EXACTLY
                if (Set::check($filterFields, 'string_exactly') && !empty($filterFields['string_exactly'])) {
                    foreach ($filterFields['string_exactly'] as $key => $field) {
                        if (is_numeric($key))
                            $key = $field;

                        if (!empty($filterData[$key]))
                            $conditions["$modelName.`$field`"] = $this->sanit($filterData[$key]);
                    }
                }
            //
            // )---------------------------------------------------------------------------------------------------
            // ----------------------------------------------------------------------------------------------------


            // ----------------------------------------------------------------------------------------------------
            // ---------------------------------------------------------------------------------------------------(
            // Dates
            //
                // DATES
                if (Set::check($filterFields, 'date') && !empty($filterFields['date'])) {
                    foreach ($filterFields['date'] as $key => $field) {
                        if (is_numeric($key))
                            $key = $field;

                        if ($condition = $this->buildFilterDateCondition($filterData["{$key}_before"]))
                            $conditions["$modelName.`$field` <"] = $condition;

                        if ($condition = $this->buildFilterDateCondition($filterData["{$key}_after"]))
                            $conditions["$modelName.`$field` >"] = $condition;
                    }
                }
            //
            // )---------------------------------------------------------------------------------------------------
            // ----------------------------------------------------------------------------------------------------
        }

        return $conditions;
    }

    /**
     * buildFilterDateCondition
     *
     * @access protected
     * @param array $dateArr
     * @return string
     */
    protected function buildFilterDateCondition($dateArr) {


        // --------------------------------------------------------------------------------------------------
        // -------------------------------------------------------------------------------------------------(
        // Check for the existence of time elements
        //
            $timePresent   = false;
            $timePopulated = false;
            if (Set::check($dateArr, 'meridian')) {

                $timePresent = true; // Yep. It's there...

                // See if any are populated
                if (!empty($dateArr['hour']) || !empty($dateArr['min']) || !empty($dateArr['meridian']))
                    $timePopulated = true;
            }
        //
        // )-------------------------------------------------------------------------------------------------
        // --------------------------------------------------------------------------------------------------



        // See if ANYTHING is populated... (if not, we don't need to be here)
        if (!empty($dateArr['year']) || !empty($dateArr['month']) || !empty($dateArr['day']) ||  ($timePresent && $timePopulated) ) {


            // ----------------------------------------------------------------------------
            // ---------------------------------------------------------------------------(
            // Build the Date string elements
            //
                if (empty($dateArr['year' ]))    $dateArr['year' ] = date('Y', time());
                if (empty($dateArr['month']))    $dateArr['month'] = '01';
                if (empty($dateArr['day'  ]))    $dateArr['day'  ] = '01';

                $dateArr['year' ] =         (int)$dateArr['year' ];
                $dateArr['month'] = str_pad((int)$dateArr['month'], 2, '0', STR_PAD_LEFT);
                $dateArr['day'  ] = str_pad((int)$dateArr['day'  ], 2, '0', STR_PAD_LEFT);
            //
            // )---------------------------------------------------------------------------
            // ----------------------------------------------------------------------------


            // -----------------------------------------------------------------------------------------------------------------
            // ----------------------------------------------------------------------------------------------------------------(
            // IF there are time elements present, build the Time string elements
            //  ... AND return the proper string
            //
                if ($timePresent) {

                    if (empty($dateArr['hour'    ]))    $dateArr['hour'    ] = '00';
                    if (empty($dateArr['min'     ]))    $dateArr['min'     ] = '00';
                    if (empty($dateArr['meridian']))    $dateArr['meridian'] = 'am';

                    $dateArr['hour'    ] =            (int)$dateArr['hour'    ];
                    $dateArr['min'     ] =    str_pad((int)$dateArr['min'     ], 2, '0', STR_PAD_LEFT);
                    $dateArr['meridian'] = strtolower(     $dateArr['meridian']);


                    // ----------------------------------------------------------------------
                    // ---------------------------------------------------------------------(
                    // Figure out what the hour should be, based on the meridian
                    //
                        if ($dateArr['meridian'] == 'am') {
                            if ($dateArr['hour'] == 12)
                                $dateArr['hour'] = '00';
                        } else {
                            if ($dateArr['hour'] != 12)
                                $dateArr['hour'] += 12;
                        }

                        $dateArr['hour'] = str_pad($dateArr['hour'], 2, '0', STR_PAD_LEFT);
                    //
                    // )---------------------------------------------------------------------
                    // ----------------------------------------------------------------------


                    // Send back the full string... (we aren't fiddling with seconds at all)
                    return "{$dateArr['year']}-{$dateArr['month']}-{$dateArr['day']} {$dateArr['hour']}:{$dateArr['min']}:00";
                }
            //
            // )----------------------------------------------------------------------------------------------------------------
            // -----------------------------------------------------------------------------------------------------------------


            // Send back the date string (sans time string elements)
            return "{$dateArr['year']}-{$dateArr['month']}-{$dateArr['day']}";
        }
        return false;
    }


    /**
     * sanit
     *
     * quick function for sanitizing data
     * 
     * @param mixed $data 
     * @param string $func 
     * @param array $extra 
     * @access public
     * @return void
     */
    protected function sanit($data, $func='escape', $extra=array())
    {
        if (is_numeric($data))
            return $data;

        App::import('Sanitize');
        if (!empty($extra))
            return Sanitize::$func($data, $extra);

        return Sanitize::$func($data);
    }


    /**
     * checkDelete
     * 
     * is a shortcut for deleting a given item provided that it is given as a 
     * parameter in the URL after the fashion:
     * http://www.somesite.com/controller/action/delete:<id>
     *
     * @access protected
     * @param string $model
     * @param string $redirPath
     * @param string $thingDeleting
     * @param string $callback function for doing something with the deleted item (before it gets deleted)
     * @param string $callbackAfterDelete function for doing something with the deleted item (after it gets deleted)
     * @param boolean $softDelete 
     * @return void
     */
    protected function checkDelete($model, $redirPath='', $thingDeleting='', $callback='', $callbackAfterDelete='', $softDelete=false)
    {
        if (isset($this->passedArgs['delete'])) {
            $id = (int)$this->passedArgs['delete'];


            // Perform any pre-delete callback
            if (!empty($callback) && method_exists($this, $callback))
                $this->$callback($id);


            // Load the model
            $this->loadModel($model);


            // If there is an after callback, let's get the record data before it gets deleted
            if (!empty($callbackAfterDelete) && method_exists($this, $callbackAfterDelete)) {
                $this->$model->contain();
                $recordData = $this->$model->findById($id);
            }


            // Delete the record
            if ($softDelete) {
                $saveData = array(
                    'id'     => $id,
                    'active' => $active,
                );
                $this->$model->save($saveData);
            } else {
                $this->$model->delete($id);
            }


            // Perform any post-delete callback
            if (!empty($callbackAfterDelete) && method_exists($this, $callbackAfterDelete))
                $this->$callbackAfterDelete($recordData);


            if (empty($thingDeleting))
                $thingDeleting = $model;
            // Set a Flash saying that this one has been deleted (changes "SomeModel" to "Some Model" using preg_replace)
            $this->Session->setFlash('The '.preg_replace('/([A-Z])/', ' \1', $thingDeleting).' has been removed');
            // refreshes the page so we can see our flash
            $this->redirect(array($redirPath));
        }
    }

    /**
     * doSave 
     * 
     * is a shortcut for saving an individual item (like a user)
     *  for example, when editing: http://.../admin/users/edit/72
     *  or for example, when adding: http://.../admin/users/add
     * 
     * $options is an array with the following possible keys:
     *     array $extraData  . . . . . . . . data that gets merged in with the $this->data['Model'] array
     *     boolean|string $redirectToEdit  . boolean, unless you want to set your own redirection path entirely
     *     string $extraRedir  . . . . . . . gets added to $this->redirect(array(...))
     *     string $thingSaving . . . . . . . the name of the thing saving
     *     string $successCallback . . . . . callback function for success. Defaults to true
     *     boolean $create . . . . . . . . . whether to perform Model->create()
     *     array $uploadOptions  . . . . . . options for uploading... REQUIRED when there is an upload
     *     boolean $unsetData  . . . . . . . whether to unset $this->data[$model]
     *
     *
     * $options['uploadOptions'] should be in the following format:
     *
     *  $options['uploadOptions'] = array(
     *      'numberUploads' => <int>,
     *      'derived_id_part' => <some unique string (probably related to the given "page")>,
     *      'thumbs' => array(<int>,<int>,...), // keys relating to the upload index... example, for Upload.2.file, this would be 2.  Used for generating thumbnails
     *  );
     *
     *
     * @param string $modelName
     * @param array $options
     * @access protected
     * @return void
     */
    protected function doSave($modelName, $options=array()) {

        // ----------------------------------------------------------------------------------------------------
        // ---------------------------------------------------------------------------------------------------(
        // Set Default $options and extract them
        //
            if (!isset($options['create'         ]))   $options['create'         ] = true   ;
            if (!isset($options['redirect'       ]))   $options['redirect'       ] = false  ;
            if (!isset($options['unsetData'      ]))   $options['unsetData'      ] = false  ;
            if (!isset($options['extraData'      ]))   $options['extraData'      ] = array();
            if (!isset($options['extraRedir'     ]))   $options['extraRedir'     ] = ''     ;
            if (!isset($options['thingSaving'    ]))   $options['thingSaving'    ] = ''     ;
            if (!isset($options['uploadOptions'  ]))   $options['uploadOptions'  ] = array();
            if (!isset($options['redirectToEdit' ]))   $options['redirectToEdit' ] = true   ;
            if (!isset($options['successCallback']))   $options['successCallback'] = ''     ;

            extract($options);

            if ($redirect === false)
                $redirect = $modelName;
        //
        // )---------------------------------------------------------------------------------------------------
        // ----------------------------------------------------------------------------------------------------


        // Ensure there is data and that it was either POSTed or PUT
        if (!empty($this->data) && isset($this->data[$modelName]) && !empty($this->data[$modelName]) && ($this->RequestHandler->isPost() || $this->RequestHandler->isPut())) {

            // Add any extra data to the data array...
            if (!empty($extraData)) {
                foreach ($extraData as $k => $v) {
                    $this->data[$modelName][$k] = $v;
                }
            }


            // If we are creating a new record
            if ($create)
                $this->$modelName->create();


            // Try saving...
            if ($this->$modelName->save($this->data)) {

                // If we are performing an upload
                if (!empty($uploadOptions)) {

                    $uploadOptions['modelName'] = $modelName;
                    $this->dealWithUploads($uploadOptions);
                }

                // Set a Flash saying that this one has been saved (changes "SomeModel" to "Some Model" using preg_replace)
                if (empty($thingSaving))
                    $thingSaving = $modelName;
                $this->Session->setFlash('The '.preg_replace('/([A-Z])/', ' \1', $thingSaving).' has been saved');

                if (!empty($successCallback))
                    $this->$successCallback();

                // Send us to where we want to go (lowercasing the first letter... too bad we don't have lcfirst in PHP5)
                if (is_bool($redirectToEdit)) {
                    if ($redirectToEdit)
                         $this->redirect(array('action' => 'edit', $this->$modelName->id, $extraRedir));
                    else $this->redirect(array('action' => (string)(Inflector::pluralize(strtolower(substr($redirect,0,1)).substr($redirect,1))), $extraRedir));
                } else {
                    $this->redirect($redirectToEdit);
                }

            } else {

                // If we are performing an upload, but the save failed
                if (!empty($uploadOptions))
                    $this->clearUnwantedUploads();


                // Hmm... something happened...
                $this->Session->setFlash("There was an error saving the $modelName.  Please check the form for errors.");
            }

            // Not sure why this is in here...  
            if ($unsetData)
                unset($this->data[$modelName]);
        }
    }

    /**
     * setIndividual
     * 
     * is a convenience function for setting up a given item
     *
     * @access protected
     * @param string $model
     * @param integer $id
     * @param array|boolean=false $contain
     * @param integer|boolean=false $recursive
     * @return void
     */
    protected function setIndividual($model, $id, $contain=false, $recursive=false)
    {
        $id = (int)$id;

        $this->$model->id = $id;

        if ($contain !== false)
            $this->$model->contain($contain);
        if ($recursive !== false)
            $this->$model->recursive = $recursive;

        if (!empty($this->data))
            array_merge($this->data, $this->$model->read());
        else $this->data = $this->$model->read();
    }


	/**
	 * Check for and delete ads that are 30 days old
	 */
	protected function expireClassifiedAds()
	{
		$this->loadModel('Classified');
		$this->Classified->deleteAll('DATEDIFF(NOW(), `Classified.created`) > 30');

	} // expireClassifiedAds()


    /**
     * dealWithUploads
     *
     * $uploadOptions should be in the following format:
     *
     *  $uploadOptions = array(
     *      'numberUploads' => <int>, // defaults to 1
     *      'derived_id_part' => <some unique string (probably related to the given "page")>, // * REQUIRED
     *      'thumbs' => array(<int>,<int>,...), // keys relating to the upload index... example, for Upload.2.file, this would be 2.  Used for generating thumbnails
     *      'modelName' => <String>, // * REQUIRED
     *  );
     * 
     * @param array $uploadOptions
     * @access protected
     * @return void
     */
    protected function dealWithUploads($uploadOptions) {

        // ----------------------------------------------------------------------------------------------------
        // ---------------------------------------------------------------------------------------------------(
        // Checking for the existence of required fields.
        //
            if (!Set::check($uploadOptions, 'derived_id_part') || empty($uploadOptions['derived_id_part']))
                throw new Exception('`derived_id_part` required in AppController::dealWithUploads()');

            if (!Set::check($uploadOptions, 'modelName') || empty($uploadOptions['modelName']))
                throw new Exception('`modelName` required in AppController::dealWithUploads()');

            $modelName = $uploadOptions['modelName'];
            $id = $this->$modelName->id;
            if (empty($id))
                throw new Exception('`id` not set in AppController::dealWithUploads()');
        //
        // )---------------------------------------------------------------------------------------------------
        // ----------------------------------------------------------------------------------------------------

            
        // ----------------------------------------------------------------------------------------------------
        // ---------------------------------------------------------------------------------------------------(
        // Set some defaults
        //
            if (!Set::check($uploadOptions, 'numberUploads') || empty($uploadOptions['numberUploads']))
                $uploadOptions['numberUploads'] = 1;

            if (!Set::check($uploadOptions, 'thumbs') || empty($uploadOptions['thumbs']))
                $uploadOptions['thumbs'] = array();
        //
        // )---------------------------------------------------------------------------------------------------
        // ----------------------------------------------------------------------------------------------------


        // ---------------------------------------------------------------
        // --------------------------------------------------------------(
        // Determine if anything was uploaded
        //
            $uploaded = false;
            for ($i=0; $i<$uploadOptions['numberUploads']; $i++) {

                if (!empty($this->data['Upload'][$i]['file']['name'])) {

                    $uploaded = true;
                    break;
                }
            }
        //
        // )--------------------------------------------------------------
        // ---------------------------------------------------------------


        // If anything *was* uploaded...
        if ($uploaded) {

            if ($this->FileUpload->success) {

                $uploadMap = array_keys($this->FileUpload->uploadedFiles);

                $this->loadModel('Upload');

                foreach ($uploadMap as $i => $k) {

                    // Update the File Upload Record as well as delete old files!  All in one step!  Wahoo!  :)
                    $this->Upload->updateFileUploadRecord( ucfirst($uploadOptions['modelName']),  (int)$id,  $uploadOptions['derived_id_part'].$k,  $this->FileUpload,  $i );
                }


                // ------------------------------------------------------------------------------------------------------------------------------------------------
                // -----------------------------------------------------------------------------------------------------------------------------------------------(
                //  Create the new thumbnail for file0 and file1 (the Logo and the Picture)
                //
                    foreach ($uploadOptions['thumbs'] as $thumbIndex) {

                        if (isset($uploadMap[$thumbIndex]) && $uploadMap[$thumbIndex] < 2 && !empty($this->data['Upload'][$uploadMap[$thumbIndex]]['file']['name'])) {
                            // Get the image dimensions of the 1st uploaded file (which is the "logo")
                            list($width, $height) = getimagesize('files/'.$this->FileUpload->finalFiles[$thumbIndex]);
                            $thumb_dimensions = $this->_resizeDimensions(200, 200, $width, $height);

                            // Create the thumbnail
                            // usage: generateThumb(sourceFileName, targetFileName, overwrite=true, display=false)
                            $this->PhpThumb->width  = $thumb_dimensions['width' ];
                            $this->PhpThumb->height = $thumb_dimensions['height'];
                            
                            $this->PhpThumb->generateThumbnail('files/'.$this->FileUpload->finalFiles[$thumbIndex], 'files/thumbs/'.$this->FileUpload->finalFiles[$thumbIndex]);
                            
                            // Update the upload record for the file
                            $uploadStuff = array(
                                'width'		   => $width,
                                'height'	   => $height,
                                'thumb_width'  => $thumb_dimensions['width'],
                                'thumb_height' => $thumb_dimensions['height'],
                                Inflector::singularize(Inflector::tableize($uploadOptions['modelName'])).'_id' => $id,
                            );

                            $this->Upload->id = $this->FileUpload->uploadIds[$thumbIndex];
                            $this->Upload->save($uploadStuff);
                        }
                    }
                //
                // )-----------------------------------------------------------------------------------------------------------------------------------------------
                // ------------------------------------------------------------------------------------------------------------------------------------------------

                return true;
            } else {

                //echo '<pre>'.print_r($this->FileUpload, true).'</pre>';
                //echo '<pre>';var_dump($this->FileUpload);echo'</pre>';
                //exit;
            }

            return false;
        }

        return true;
    }

	/**
	 * Calculate restricted dimensions with a maximum 
	 * of $goal_width x $goal_height
	 * and return an array with the new height and width.
	 *
	 * @param int $goal_width
	 * @param int $goal_height
	 * @param int $width
	 * @param int $height
	 *
	 * @return array
	 */
	private function _resizeDimensions($goal_width, $goal_height, $width, $height) 
	{
    	$return = array('width' => $width, 'height' => $height);
		if (empty($width) || empty($height))
		{
			return $return;
		}
		   
		// If the ratio > goal ratio and the width > goal width resize down to goal width
		if ($width/$height > $goal_width/$goal_height && $width > $goal_width) 
		{
			$return['width'] = $goal_width;
			$return['height'] = $goal_width/$width * $height;
		}
		// Otherwise, if the height > goal, resize down to goal height
		else if ($height > $goal_height) 
		{
			$return['width'] = $goal_height/$height * $width;
			$return['height'] = $goal_height;
		}
		
		return $return;
	
	} // _resizeDimensions()

}
?>

Open in new window

0
Comment
Question by:brucegust
2 Comments
 
LVL 2

Accepted Solution

by:
ondrejsimek earned 500 total points
ID: 33707361
Is there something special in the User model? I would try debugging in the model callbacks, e.g. placing the following code in beforeSave and beforeValidate.
debug($this->data); die;

Open in new window

0
 

Author Comment

by:brucegust
ID: 33716702
Thanks for getting back with ondrejsimek.

I was able to locate the update statement and it turned out to be something I could fix by repositioning the appropriate actions within the if statement that was qualifiying things, but not actually allowing the system to "do" anything.

Thanks for your feedback. I'll keep your suggestion in mind for the next time I'll need some debugging.
0

Featured Post

Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

Join & Write a Comment

Foreword (July, 2015) Since I first wrote this article, years ago, a great many more people have begun using the internet.  They are coming online from every part of the globe, learning, reading, shopping and spending money at an ever-increasing ra…
This article discusses four methods for overlaying images in a container on a web page
Learn how to match and substitute tagged data using PHP regular expressions. Demonstrated on Windows 7, but also applies to other operating systems. Demonstrated technique applies to PHP (all versions) and Firefox, but very similar techniques will w…
The viewer will learn how to dynamically set the form action using jQuery.

758 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now