<?php
/*
Officity - Web application platform - Version 6.0 - 2011-07-05

François Dispaux, Boris Verdeyen, Thomas Hermant,
Jérémie Roy, Grégory Meurice, Abdelila Harbi, 
Marc Mignonsin, Jonathan Sanchez, Julien Gonzalez, Pierre Fouchez

Sushee and Officity is © Copyright 2011 Nectil SA.

`/var/www/installer/public_html/officity-source/apps/system/class/AbstractElementOperation.class.php` is part of Officity.

Sushee is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Officity and Sushee are distributed in the hope that they will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Sushee. If not, see <http://www.gnu.org/licenses/>.
*/
	require_once(dirname(__FILE__).'/AbstractOperation.class.php');
	
	/* *** */

	/*
	 * AbstractElementOperation Class
	 * 
	 * @since	2010-11-24
	 *
	*/
    
	abstract class AbstractElementOperation extends AbstractOperation 
	{	
		const EXECUTE = true;
		
		protected $element;
		
		function __construct($element)
		{
			parent::__construct();
			$this->element = $element;
		}
		
		function __destruct()
		{
			
		}
		
		protected function _execute($method_name)
		{			
			if (!is_object($this->element))
			{
				$class_name = get_class($this);
				$this->abort('Operation on a non-object element in "'.$class_name.'->'.$method_name.'"!');
			}			

			$this->JSON_response->set('module', $this->element->getDenomination());

			return $this->$method_name();
		}
		
		public function abort($output_message='')
		{
			$this->JSON_response->set('NQL', $this->element->getNQLCommand()); // log NQL
			if (empty($output_message))
			{
				$output_message = 'Operation failed: '.$this->element->getLastError();
			}
			throw new OfficityException($output_message,  $this->JSON_response);
		}
		
		public function success($output_message='')
		{
			if (self::EXECUTE == false)
			{
				$this->JSON_response->set('NQL', $this->element->getNQLCommand());
			}
			
			$this->JSON_response->set('now', date('Y-m-d H:i:s')); // for form updates (e.g.: MODIFICATIONDATE)
			$this->JSON_response->outputSuccess($output_message);
		}
		
		public function error($output_message='')
		{
			$this->JSON_response->set('NQL', $this->element->getNQLCommand()); // log NQL
			if (empty($output_message))
			{
				$output_message = 'Operation failed: '.$this->element->getLastError();
			}
			$this->JSON_response->outputError($output_message);
		}
		
		public function warning($output_message='')
		{
			$this->JSON_response->set('NQL', $this->element->getNQLCommand()); // log NQL
			if (empty($output_message))
			{
				$output_message = 'Operation warning: undefined.';
			}
			$this->JSON_response->outputWarning($output_message);
		}
		
		public function info($output_message='')
		{
			if (empty($output_message))
			{
				$output_message = 'Operation info: undefined.';
			}
			$this->JSON_response->outputInfo($output_message);
		}
	
		/* *** */
		
		// CREATE
		public function _create()
		{
			$result = false;
			
           	$this->element->parse($_POST);
	
           	// dependency : optional
           	if (URLParam::isNotEmpty('dependency') && 
	           	URLParam::isNotEmpty('targetModule') && 
	           	URLParam::isNotEmpty('targetID'))
           	{                
	        	$this->element->setDependencyByName(
	            	$this->fetchURLParam('dependency'), 
	               	$this->fetchURLParam('targetModule'), 
	               	$this->fetchURLParam('targetID'),
	               	$this->fetchURLParam('mode', 'reverse'), 
	               	'append'
               	);
           	}
           	else
           	{
	    		if (URLParam::isNotEmpty('dependency') || 
	            	URLParam::isNotEmpty('targetModule') || 
	            	URLParam::isNotEmpty('targetID'))
	           	{
	            	// throw exception
	                $this->fetchURLParam('dependency');
	                $this->fetchURLParam('targetModule'); 
	                $this->fetchURLParam('targetID');
	           	}
			}
			
			//$this->element->logCommand();

	        $result = $this->element->create(self::EXECUTE);  
	        if ($result === true)
	        {
	        	$this->JSON_response->set('ID', $this->element->getID());
	        	
	        	// upload files and update
               	$upload_result = $this->element->uploadFiles(true, self::EXECUTE);               	
               	if ($upload_result == false)
               	{
               		//$this->warning('Upload failed: '.$this->element->getLastError());
               	}
	        }
	           
	        return $result;
		}
		
		// UPDATE
		public function _update()
		{
	           $this->element->setID($this->fetchURLParam('ID'));            
	           $this->element->parse($_POST);        
	           //$this->element->logCommand();    
			        	
	           // upload files and no update
               $upload_result = $this->element->uploadFiles(false, self::EXECUTE);
	            
	           $result = $this->element->update(self::EXECUTE);
	           if ($result == false)
	           {
	           		$this->abort();
	           }
	           
                if ($upload_result != true)
	            {
	            	//$this->warning('Upload failed: '.$this->element->getLastError());
	            }
	            
		        return $result;
	            // $this->success();
		}
		
		// MASSIVE UPDATE (SEARCH EDIT)
		public function _searchUpdate()
		{
		    $elements_array = array();
		    
		    // 1st pass : parse
		    foreach ($_POST as $key => $value)
		    {
		    	list($prefix, $module, $field, $field_type, $element_ID) = explode('-', $key, 5);
		    	
		    	// checks
		    	if ($prefix != 'info') continue;
		    	
		    	if (!isset($elements_array[$element_ID]))
		    	{
		    		$module = str_replace('__', ':', $module);
		    		$elements_array[$element_ID] = new Element($module, $element_ID);
		    	}	    	
		    	
		    	$field = str_replace('__', ':', $field);
		    	$elements_array[$element_ID]->setInfo($field, $value);
		    }
		    
		    // 2nd pass : update
		    $success_IDs = array();
		    foreach ($elements_array as $element)
		    {
		    	$current_ID = $element->getID();
		    	
		    	$result = $element->update(self::EXECUTE);
		    	if ($result !== true)
				{
					$this->JSON_response->set('Success IDs', $success_IDs);
					$this->JSON_response->set('Error ID', $current_ID);
			        $this->abort('Update failed on '.$element->getDenomination().' ID='.$current_ID.': '.$element->getLastError().' / '.count($success_IDs).'element(s) updated.');
				}
				$success_IDs []= $current_ID;
		    }
		    	    
		    $this->JSON_response->set('Success IDs', $success_IDs);
		    $this->success(count($elements_array).' element(s) successfully updated!');
		}
		
		// DELETE
		public function _delete()
		{
	           $this->element->setID($this->fetchURLParam('ID'));            
	           return $this->element->destroy(self::EXECUTE);
		}
		
		// DUPLICATE
		public function _duplicate()
		{
	           $this->element->setID($this->fetchURLParam('ID'));          
	           if ($this->element->duplicate(self::EXECUTE) == true)
	           {
	           		$this->JSON_response->set('ID', $this->element->getID());
	           		return true;
	           }
	           return false;
		}
		
		// ADD/REMOVE DEPENDENCY
		public function _link()
		{
	           $this->element->setID($this->fetchURLParam('ID'));
	           $this->element->setDependencyByName(
	           	$this->fetchURLParam('dependency'), 
	           	strtoupper($this->fetchURLParam('targetModule')), 
	           	$this->fetchURLParam('targetID'), 
	           	'reverse', 
	           	'append'
	           );
	           
	           //$this->element->logCommand();
	           	           
	           return $this->element->update(self::EXECUTE);
		}
		
		public function _unlink()
		{
	           $this->element->setID($this->fetchURLParam('ID'));
	           $this->element->setDependencyByName(
	           	$this->fetchURLParam('dependency'), 
	           	strtoupper($this->fetchURLParam('targetModule')), 
	           	$this->fetchURLParam('targetID'), 
	           	'reverse', 
	           	'remove'
	           );
	           //$this->element->logCommand();
	           return $this->element->update(self::EXECUTE);
		}
		
		// COUNT
		public function _count()
		{            
			session_write_close(); // optim: unlock session data and allow concurrent accesses to this script
			
	        $hits = $this->element->count(self::EXECUTE);
	        if ($hits !== false)
	        {
	        	$this->success($hits);
	        }
	          
	        return false;
		}
		
		// SORT ELEMENTS IN DEPENDENCY
        public function _sortDeps()
        {
            $this->element->setID($this->fetchURLParam('ID'));

            $DEPENDENCY_TYPE = $this->fetchURLParam('dependency');
            $DEPENDENCY_MODULE = $this->fetchURLParam('targetModule');
            $SORTED_IDS = $this->fetchURLParam('sortedIDs');

            foreach ($SORTED_IDS as $ID)
            {            	
                $this->element->setDependencyByName($DEPENDENCY_TYPE, $DEPENDENCY_MODULE, $ID, 'normal', 'replace');
            }

            return $this->element->update(self::EXECUTE);
        }
		
		// ASSIGN SECURITY
		public function _assignSecurity()
		{
			$this->element->setID($this->fetchURLParam('ID')); 
			
		    $TYPE = strtoupper($this->fetchURLParam('type'));
			if ($TYPE == 'GROUPS')
			{            
            	return $this->element->assignGroupsSecurity(
            		$this->fetchURLParam('targetIDs'), 
            		$this->fetchURLParam('newSetting'), 
            		self::EXECUTE
            	);
			}
			else if ($TYPE == 'OWNERS')
			{
            	return $this->element->assignOwnersSecurity(
            		$this->fetchURLParam('targetIDs'), 
            		$this->fetchURLParam('newSetting'), 
            		self::EXECUTE
            	);				
			}

			$this->abort('Invalid type "'.$TYPE.'"!');
		}
	}
?>