<?php

/**************************************************************
* This file is part of Remository
* Copyright (c) 2006-17 Martin Brampton
* 
* License: GNU General Public License version 2 or later; see LICENSE.txt
* 
* For support and other information, visit http://remository.com
* To contact Martin Brampton, write to martin@remository.com
*
* Remository started life as the psx-dude script by psx-dude@psx-dude.net
* It was enhanced by Matt Smith up to version 2.10
* Since then development has been primarily by Martin Brampton,
* with contributions from other people gratefully accepted
*/

defined('_JEXEC') or die;

class remositoryControllerContainers extends remositoryAdminControllers {

	public function __construct (&$admin) {
		parent::__construct ($admin);
		$this->parentid = remositoryRepository::getParam($_REQUEST, 'parentid', 0);
	    $_REQUEST['act'] = 'containers';

	}

	public function listTask () {
		// Get the search string that will constrain the list of containers displayed
		$search = trim( strtolower( remositoryRepository::getParam( $_POST, 'search', '' ) ) );
		// Get the flag that tells us whether to continue to nested containers right down to the bottom
		$descendants = intval(remositoryRepository::getParam($_POST, 'descendants', 0));
		// Create the container above our present position - might be degenerate
		$container = new remositoryContainer($this->parentid);
		// Get all the containers that are to be displayed
		if ($descendants) {
			$folders = $container->getDescendants($this->admin->limitstart, $this->admin->limit, $search);
			$total = $container->countDescendants($search);
		}
		else {
			$folders = $container->getSelectedChildren($this->admin->limitstart, $this->admin->limit, $search);
			$total = $container->countChildren($search);
		}
		clearstatcache();
		foreach ($folders as $key=>$folder) {
			if ($folder->filepath) {
				if ('/' != $folder->filepath[0] AND !preg_match('#^[a-z]:/#i', $folder->filepath)) $pathstatus = '<span class="remositoryred">'._DOWN_NOT_ABSOLUTE.'</span>';
				elseif (file_exists($folder->filepath)) {
					if (is_writeable($folder->filepath)) $pathstatus = _DOWN_FILE_SYSTEM_OK;
					else $pathstatus = '<span class="remositoryred">'._DOWN_NOT_WRITEABLE.'</span>';
				}
				else $pathstatus = '<span class="remositoryred">'._DOWN_DIRECTORY_NON_EXISTENT.'</span>';
			}
			else $pathstatus = _DOWN_DATABASE;
			$folders[$key]->pathstatus = $pathstatus;
		}
		// Generate a container list for user to select where to be
		$manager = remositoryContainerManager::getInstance();
		if ($manager->count() < 100) $clist = $container->getSelectList('parentid', 'class="inputbox" size="1" onchange="document.adminForm.submit();"', $this->remUser);
		else {
			$clist = _DOWN_MANY_CONTAINERS;
			$clist .= <<<HIDDEN_PARENT

				<input type="hidden" name="parentid" value="$container->id" />

HIDDEN_PARENT;

		}
		// Create and activate a View object
		$view = $this->admin->newHTMLClassCheck ('listContainersHTML', $this, $total, $clist);
		$view->view($container, $folders, $descendants, $search);
	}

	public function addTask () {
		// This is the parent container for our current location to generate clist
		$currparent = remositoryRepository::getParam($_REQUEST, 'currparent', 0);
		$container = new remositoryContainer($currparent);
		$interface = remositoryInterface::getInstance();
		$subsinfo = $interface->triggerMambots('querySubscriptionCount', array('com_remository', 0, 0));
		// Generate a container list so the user can change the parent
		$clist = $container->getSelectList('parentid', 'class="inputbox"', $this->remUser);
		// Now create empty container
		$container = new remositoryContainer();
		// Create and activate a View object
		$view = $this->admin->newHTMLClassCheck ('editContainersHTML', $this, 0, $clist);
		foreach (remositoryContainer::$actions as $action) $selector[$action] = $this->getRoleSelect(null, $action);
		$view->view($container, $selector, count($subsinfo));
	}

	public function editTask () {
		// Create a container object that will be filled with data from the DB using currid as key
		$container = new remositoryContainer($this->admin->currid);
		$parent = new remositoryContainer($container->parentid);
		if (0 == $container->id) {

		}
		$interface = remositoryInterface::getInstance();
		$subsinfo = $interface->triggerMambots('querySubscriptionCount', array('com_remository', 0, 0));
		// Generate a container list so the user can change the parent
		$clist = $parent->getSelectList('parentid', 'class="inputbox"', $this->remUser, $container->id);
		// Create and activate a View object
		$view = $this->admin->newHTMLClassCheck ('editContainersHTML', $this, 0, $clist);
		foreach (remositoryContainer::$actions as $action) $selector[$action] = $this->getRoleSelect($container, $action);
		$view->view($container, $selector, count($subsinfo));
	}

	// This is a private function
	private function getRoleSelect ($container, $action) {
		$defaults = array(
		'upload' => 'Registered',
		'download' => 'Public',
		'edit' => 'Nobody'
		);
		$defaults['selfApprove'] = $this->repository->Enable_User_Autoapp ? 'Registered' : 'Nobody';
		$authoriser = aliroAuthorisationAdmin::getInstance();
		$roles = $authoriser->getAllRoles(true);
		if ($container) $selected = $authoriser->permittedRoles ($action, 'remosFolder', $container->id);
		elseif (isset($defaults[$action])) $selected = array($defaults[$action] => 1);
		else $selected = array();
		foreach ($roles as $role=>$translated) $selector[] = $this->repository->makeOption($role, $translated);
		if (isset($selector)) return $this->repository->selectList ($selector, 'permit_'.$action.'[]', 'multiple="multiple"', array_keys($selected));
		else return 'This is the role selector';
	}

	public function saveTask () {

		$container = $this->commonSave();
		// Next we locate ourselves where this container has finished up and list containers
		$this->parentid = $container->parentid;
        JFactory::getApplication()->enqueueMessage(_DOWN_CONTAINER_SAVED, 'message');
		$this->listTask();
	}

	public function applyTask () {
		$this->commonSave();
        JFactory::getApplication()->enqueueMessage(_DOWN_CONTAINER_SAVED, 'message');
		$this->editTask();
	}

	public function deleteimageTask(){
		$interface = remositoryInterface::getInstance();
		$result = remositoryRepository::doSQLget("SELECT container_image FROM #__downloads_containers WHERE id = '".$this->admin->currid."' ",'remositoryContainer');
		if(count($result)>0){
			//$file_ext = @remositoryAbstract::lastPart($result[0]->container_image,'.');
			$imageExistingThumb = $interface->getCfg('absolute_path')."/components/com_remository_files/folder_image_".$this->admin->currid."/th_".$result[0]->container_image;
			$imageExistingMain = $interface->getCfg('absolute_path')."/components/com_remository_files/folder_image_".$this->admin->currid."/img_".$result[0]->container_image;

			if(file_exists($imageExistingThumb)){
				unlink ($imageExistingThumb);
				unlink ($imageExistingMain);
				//remositoryRepository::doSQL("UPDATE #__downloads_containers SET container_image	='' WHERE id = '".$this->admin->currid."' ");
				JFactory::getApplication()->enqueueMessage(_DOWN_SUBCONTAINER_IMAGE_DELETE_MESSAGE, 'message');
			}
		}
		$this->listTask();
	}

	private function commonSave () {
		// Create a container object that will be filled with data from the DB using currid as key
	    $container = new remositoryContainer($this->admin->currid);
	    // Clear tick box fields as nothing will be received if they are unticked
	    $container->published = $container->plaintext = 0;
	    // Add the new information from the form just submitted
	    $container->addPostData();
	    if ($container->plaintext) $container->filepath = '';
	    // By default, a new container is automatically published
	    if ($this->admin->currid == 0) $container->published = 1;
	    // Check for anomalies in the file path specified, if any
	    $container->checkFilePath();
	    // If fields are to be inherited by descendants, do it
	    $inheritpath = empty($_POST['inheritpath']) ? false : true;
	    if ($inheritpath) $container->makeDescendantsInherit();
	    $inherit = empty($_POST['inherit']) ? false : true;
	    // Save the new information about the container to the database
	    $container->saveValues ();
	    // Handle the permissions
	    $this->savePermissions($container, $inherit);
	    // Update the memorandum fields held in any files within this container
	    remositoryFile::storeMemoFields($container, $inheritpath);
	    // Move files as necessary
	    $this->relocateFilesCorrectly();
	    // Remove any orphan entries in the blob table
		remositoryRepository::doSQL("DELETE LOW_PRIORITY #__downloads_blob FROM #__downloads_blob LEFT JOIN #__downloads_files ON #__downloads_blob.fileid = #__downloads_files.id WHERE #__downloads_files.id IS NULL");
	    // The changes may well have altered the file/folder counts, so recalculate
		$this->repository->resetCounts();
        //set current editing container id
        $this->admin->currid = $container->id;

		if(isset($_FILES['container_image'])){
			$interface = remositoryInterface::getInstance();

			$handleUpload = $this->handleUpload();

			if($handleUpload->uploaded){
				$file_to_fix = $handleUpload->proper_name;
				$file_ext = @remositoryAbstract::lastPart($file_to_fix,'.');
				if ($file_ext != 'png' AND $file_ext != 'jpg' AND $file_ext != 'jpeg' AND $file_ext != 'gif') {

					JFactory::getApplication()->enqueueMessage(_DOWN_SUBCONTAINER_IMAGE_TYPE_WARNING, 'error');

				}else{
					$filepath = $interface->getCfg('absolute_path').$this->baseFilePath().$this->dirPattern().$this->admin->currid;
					if (!is_dir($filepath)) mkdir($filepath);
					//$file_to_fix = $filepath."/".$handleUpload->proper_name;

					/*$directory = new remositoryDirectory($filepath);
					$files = $directory->listFiles('img_');

					foreach ($files as $file) {
						preg_match('/^img_([0-9]*)\.(jpg|png|gif|jpeg)$/', $file, $matches);
						if ($matches[1] > $max) $max = $matches[1];
					}*/
					$max = 0;
					$oldindex=0;
					if(!empty($container->container_image)){
						$oldindex= $max = explode(".",$container->container_image)[0];
					}
					$max = $max +1;
					$newfilename = ($max).".".$file_ext;
					$file_to_fix = $filepath."/".$newfilename;

					if (move_uploaded_file($handleUpload->file_path, $file_to_fix)) {
						if (file_exists($file_to_fix)) {
							$large_image = $filepath.'/img_'.$max.".".$file_ext;
							$small_image = $filepath.'/th_'.$max.".".$file_ext;
							$repository = remositoryRepository::getInstance();
							$this->imgresize($file_to_fix, $large_image, $repository->Large_Image_Width, $repository->Large_Image_Height, true);
							$physicalimage = new remositoryPhysicalFile();
							$physicalimage->setData($large_image);
							$physicalimage->setPerms();
							$this->imgresize($file_to_fix, $small_image, $repository->Small_Image_Width, $repository->Small_Image_Height, true);
							$physicalimage->setData($small_image);
							$physicalimage->setPerms();
							unlink ($file_to_fix);

							$large_image_old = $filepath.'/img_'.($oldindex).".".$file_ext;
							$small_image_old = $filepath.'/th_'.($oldindex).".".$file_ext;

							if(file_exists($large_image_old)){
								unlink ($large_image_old);
								unlink ($small_image_old);
							}

						}

						remositoryRepository::doSQL("UPDATE #__downloads_containers SET container_image	='".$newfilename."' WHERE id = '".$this->admin->currid."' ");
						$container->container_image = $newfilename;

					}
				}
			}
		}

		return $container;
	}
	private static function baseFilePath () {
		return '/components/com_remository_files/';
	}

	private static function dirPattern () {
		return 'folder_image_';
	}
	private function imgresize($origfile,$newfile,$new_w,$new_h, $highQuality=false)
	{
		if (!function_exists('imagecreate')) {
			copy ($origfile, $newfile);
			return;
		}
		//determine starting type and create blank
		//you could also add gif and bmp in here
		$type=@remositoryAbstract::lastPart($origfile,'.');
		if ($type=="jpg" || $type=="jpeg") $src_img = imagecreatefromjpeg($origfile);
		if ($type=="png") $src_img = imagecreatefrompng($origfile);
		if ($type=="gif") $src_img = imagecreatefromgif($origfile);

		//grab original sizes
		$old_x = imagesx($src_img);
		$old_y = imagesy($src_img);

		// math to figure aspect ratio
		$ratio = min($new_w/$old_x, $new_h/$old_y);
		$thumb_h = $old_y * $ratio;
		$thumb_w = $old_x * $ratio;

		//generate a blank final image
		$dst_img = ImageCreateTrueColor($thumb_w,$thumb_h);
		//this resamples the original image and I think uses bicub to create a new image
		imagecopyresampled($dst_img, $src_img, 0, 0, 0, 0, $thumb_w, $thumb_h, $old_x, $old_y);

		// $waterfile = '/home/myremos/www/hit/images/Sample-trans.png';
		if (!empty($waterfile)) {
			$watermark = imagecreatefrompng($waterfile);
			$sized_water = ImageCreateTrueColor($thumb_w,$thumb_h);
			// Match desired image size
			imagecopyresampled($sized_water, $watermark, 0, 0, 0, 0, $thumb_w, $thumb_h, imagesx($watermark), imagesy($watermark));
			imagedestroy($watermark);
			// Make the background transparent
			imagecolortransparent($sized_water, imagecolorallocate($sized_water, 0, 0, 0));
			imagecopymerge($dst_img, $sized_water, 0, 0, 0, 0, $thumb_w, $thumb_h, 50);
			imagedestroy($sized_water);
		}

		//unlink it if it already exists in destination
		if(file_exists($newfile)) {
			chmod($newfile, 0646);
			unlink($newfile);
		}

		//create the final file
		if ($type=="png") {
			if ($highQuality) imagepng($dst_img,$newfile,0);
			else imagepng($dst_img,$newfile);
		}
		elseif ($type=="gif") imagegif($dst_img,$newfile);
		else {
			if ($highQuality) imagejpeg($dst_img,$newfile,100);
			else imagejpeg($dst_img,$newfile);
		}

		//free up memory
		imagedestroy($dst_img);
		imagedestroy($src_img);
	}
	public function handleUpload ($suffix='') {
		$key = 'container_image'.$suffix;
		$handleUpload = new stdClass();

		if (!isset($_FILES[$key]) OR $_FILES[$key]['tmp_name']=='none' OR $_FILES[$key]['tmp_name']==''){
			return $handleUpload->error_message =_ERR1;

		}
		if ($_FILES[$key]['error']) {
			return $handleUpload->error_message = _ERR11;

		}
		$handleUpload->proper_name = remositoryRepository::getParam($_FILES[$key], 'name');
		if ($_FILES[$key]['size'] == 0) {
			return $handleUpload->error_message = _ERR3;

		}
		$handleUpload->size = remositoryRepository::getParam($_FILES[$key], 'size', 1024)/1024;
		$repository = remositoryRepository::getInstance();
		if($handleUpload->size > $repository->MaxSize) {
			return $handleUpload->error_message =  _ERR5.$repository->MaxSize.' Kb';

		}
		$handleUpload->size = number_format($handleUpload->size,2).' Kb';
		if (!is_uploaded_file($_FILES[$key]['tmp_name'])) {
			return $handleUpload->error_message = _ERR2;
		}
		else $handleUpload->file_path = $_FILES[$key]['tmp_name'];
		if (ini_get('safe_mode')) $handleUpload->date = date('Y-m-d H:i:s');
		else $handleUpload->date = $this->fileDate($handleUpload->file_path);
		$handleUpload->uploaded = true;
		$handleUpload->withid = false;
		return $handleUpload;
	}
	private function fileDate ($filepath) {
		$unixtime = @filemtime($filepath);
		if (0 == $unixtime) $unixtime = time();
		return date('Y-m-d H:i:s', $unixtime);
	}
	// Private function for tidiness
	private function savePermissions ($container, $inherit) {
		$authoriser = aliroAuthorisationAdmin::getInstance();
		$interface = remositoryInterface::getInstance();
		foreach (remositoryContainer::$actions as $action) {
			$this->dropPermissions($authoriser, $action, $container, $inherit);
			$roles = remositoryRepository::getParam($_POST, 'permit_'.$action, array());
			if (in_array('Public', $roles)) continue;
			if (in_array('Registered', $roles)) {
				$this->grantPermissions($authoriser, 'Registered', $action, $container, $inherit);
				continue;
			}
			$extra = remositoryRepository::getParam($_POST, 'new_role_'.$action);
			if ($extra) $roles[] = $extra;
			foreach ($roles as $role) {
				$role = $interface->getEscaped($role);
				if ('none' != $role) $this->grantPermissions($authoriser, $role, $action, $container, $inherit);
			}
		}
	}

	private function dropPermissions ($authoriser, $action, $container, $inherit) {
		$authoriser->dropPermissions($action, 'remosFolder', $container->id);
		if ($inherit) {
			$descendants = $container->getDescendants();
			foreach ($descendants as $descendant) $authoriser->dropPermissions($action, 'remosFolder', $descendant->id);
		}
	}

	private function grantPermissions ($authoriser, $role, $action, $container, $inherit) {
		$authoriser->permit ($role, 2, $action, 'remosFolder', $container->id);
		if ($inherit) {
			$descendants = $container->getDescendants();
			foreach ($descendants as $descendant) $authoriser->permit ($role, 2, $action, 'remosFolder', $descendant->id);
		}
	}

	public function deleteTask (){
		// In case the Javascript cannot do the check, ensure at least one item selected
		$this->admin->check_selection(_DOWN_SEL_FILE_DEL);
		// For each selected container, create an object then delete (will delete from DB)
		$authoriser = aliroAuthorisationAdmin::getInstance();
		foreach ($this->admin->cfid as $id) {
			$container = new remositoryContainer($id);
			foreach (remositoryContainer::$actions as $action) $this->dropPermissions($authoriser, $action, $container, false);
			$this->parentid = $container->parentid;

			$interface = remositoryInterface::getInstance();
			$imageExistingThumb = $interface->getCfg('absolute_path')."/components/com_remository_files/folder_image_".$container->id."/th_".$container->container_image;
			$imageExistingMain = $interface->getCfg('absolute_path')."/components/com_remository_files/folder_image_".$container->id."/img_".$container->container_image;

			if(file_exists($imageExistingThumb)){
				unlink ($imageExistingThumb);
				unlink ($imageExistingMain);
			
			}
			$container->deleteAll();
		}

        $message = count($this->admin->cfid)>1?_DOWN_CONTAINERS_DELETED:_DOWN_CONTAINER_DELETED;
        JFactory::getApplication()->enqueueMessage($message, 'message');

		// The file/folder counts will have been upset, so recalculate
		$this->repository->resetCounts();


		// Now show the list of containers again
		$this->listTask();
	}

	public function publishTask () {
        $message = count($this->admin->cfid)>1?_DOWN_CONTAINERS_PUBLISHED:_DOWN_CONTAINER_PUBLISHED;
        JFactory::getApplication()->enqueueMessage($message, 'message');
		$this->publishToggle(1);
	}

	public function unpublishTask () {
        $message = count($this->admin->cfid)>1?_DOWN_CONTAINERS_UNPUBLISHED:_DOWN_CONTAINERS_UNPUBLISHED;
        JFactory::getApplication()->enqueueMessage($message, 'message');
		$this->publishToggle(0);
	}

	private function publishToggle ($publish) {
		// Check that one or more items have been selected (Javascript may not have run)
		$this->admin->check_selection(_DOWN_PUB_PROMPT.($publish ? 'publish' : 'unpublish'));
	    remositoryContainer::togglePublished($this->admin->cfid,$publish);
	    // The file/folder counts only include published items, so recalculate
		$this->repository->resetCounts();
		// List out the containers again
		if (isset($this->admin->cfid[0])) {
		    $container = new remositoryContainer($this->admin->cfid[0]);
		    $this->parentid = $container->parentid;
		}
		$this->listTask();
	}

}
