diff --git a/.htaccess b/.htaccess
index fc3aac4b..370112c1 100644
--- a/.htaccess
+++ b/.htaccess
@@ -2,4 +2,9 @@
RewriteEngine on
RewriteRule ^$ webroot/ [L]
RewriteRule (.*) webroot/$1 [L]
-
\ No newline at end of file
+
+
+
+Header add Access-Control-Allow-Origin "*"
+Header add Access-Control-Allow-Headers "origin, x-requested-with, content-type"
+Header add Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"
diff --git a/Config/core.php b/Config/core.php
index 871622a6..270c88a9 100644
--- a/Config/core.php
+++ b/Config/core.php
@@ -263,7 +263,7 @@
/**
* A random string used in security hashing methods.
*/
- Configure::write('Security.salt', 'DYhG93b0qyJfIxfs2guVoUubWwvniR2G0FgaC9mi');
+ Configure::write('Security.salt', '2Q6HX62YKE7FEtJsg4KS9Mg1tOyedpOV5KcSGVqRi');
/**
* A random numeric string (digits only) used to encrypt/decrypt strings.
@@ -430,3 +430,20 @@
'serialize' => ($engine === 'File'),
'duration' => $duration
));
+
+// In development mode, caches should expire quickly.
+$durationCacheDB = '+8 hours';
+if (Configure::read('debug') > 0) {
+ $durationCacheDB = '+1 minutes';
+}
+
+/**
+ * Configure the cache for database queries
+ */
+Cache::config('_cake_db_', array(
+ 'engine' => $engine,
+ 'prefix' => $prefix . 'db_',
+ 'path' => CACHE . 'db' . DS,
+ 'serialize' => ($engine === 'File'),
+ 'duration' => $durationCacheDB
+));
diff --git a/Controller/BrowserController.php b/Controller/BrowserController.php
index a3afdbbe..1fd397fc 100644
--- a/Controller/BrowserController.php
+++ b/Controller/BrowserController.php
@@ -327,7 +327,106 @@ public function import() {
$this->FilterManager->ImageFilter->Exiftool->exitExiftool();
$this->redirect('index/'.$path);
}
+
+ private function _lsyncimport($filetoimport) {
+
+ if ($this->hasRole(ROLE_ADMIN)) {
+ ini_set('max_execution_time', 3600);//1 hour
+ }
+
+ $options = array();
+ $options['recursive'] = 1;
+ $options['forceReadMeta'] = 1;
+ $options['extensions'] = array('any');
+
+ $recursive = (bool) $options['recursive'];
+
+ // Get dir and imports
+ $dirs = array();
+ $files = array();
+ $toRead = array();
+
+ #$fsPath = $this->_getFsPath($filetoimport);
+ $fsPath = $filetoimport;
+ if (is_dir($fsPath)) {
+ $dirs[] = Folder::slashTerm($fsPath);
+ $toRead[] = $fsPath;
+ } elseif (file_exists($fsPath) && is_readable($fsPath)) {
+ $files[] = $fsPath;
+ $toRead[] = $fsPath;
+ }
+
+ $this->FilterManager->clearErrors();
+
+ $readed = $this->FilterManager->readFiles($toRead, $options);
+ $skipped = count($this->FilterManager->skipped);
+ $errorCount = count($this->FilterManager->errors);
+
+ $readCount = 0;
+ foreach ($readed as $file => $media) {
+ if ($media) {
+ $readCount++;
+ }
+ }
+ $this->Session->setFlash(__("Processed %d files (imported %d, skipped %d, %d errors)", $readCount, $readCount-$skipped, $skipped, $errorCount));
+
+ $this->FilterManager->ImageFilter->Exiftool->exitExiftool();
+ return true;
+ }
+
+ private function _lsyncdelete($filename=''){
+
+ if($filename != ''){
+ $file = $this->MyFile->findByFilename($filename);
+ if (!$file) {
+ return false;
+ } elseif ($file['User']['id'] != $this->getUserId()) {
+ return false;
+ } else {
+ $this->Session->setFlash(__("Media %d was unlinked successfully", $file['File']['media_id']));
+ $this->Media->unlinkFile($file['File']['media_id'], $file['File']['id']);
+ }
+ echo 'OK';
+ exit;
+ }
+ echo 'Nothing to do here';
+ exit;
+ }
+
+
+ public function lsyncd(){
+
+ if(isset($this->request->data['lsynclog']) && isset($this->request->data['folder_root'])){
+ $lsynclog=$this->request->data['lsynclog'];
+ $folder_root = $this->request->data['folder_root'];
+ $files = file($lsynclog);
+
+
+ for($i=0;$i';
+ // archivo nuevo, llamo a import
+ #$this->_lsyncimport($folder_root.'/'.trim($file[4]));
+ $this->_lsyncimport($folder_root.trim($file[4]));
+
+ } elseif($file[3] == "*deleting"){
+ #echo 'archivo eliminado'.$folder_root.trim($file[4]).'
';
+ #$this->_lsyncdelete($folder_root.'/'.trim($file[4]));
+ $this->_lsyncdelete($folder_root.trim($file[4]));
+ // archivo borrado, llamo a delete
+ }
+ }
+ }
+ exit;
+ }
public function unlink() {
$path = $this->_getPathFromUrl();
$fsPath = $this->_getFsPath($path);
diff --git a/Controller/Component/ExiftoolComponent.php b/Controller/Component/ExiftoolComponent.php
index 01497fa3..4980ddf4 100644
--- a/Controller/Component/ExiftoolComponent.php
+++ b/Controller/Component/ExiftoolComponent.php
@@ -519,6 +519,9 @@ public function extractImageDataSidecar(&$media, &$data) {
$v['shutter'] = $this->_extract($data, 'ShutterSpeed', $v['shutter']);
$v['model'] = $this->_extract($data, 'Model', $v['model']);
$v['iso'] = $this->_extract($data, 'ISO', $v['iso']);
+ if(is_array($v['iso'])){
+ $v['iso'] = null;
+ }
$v['caption'] = $this->_extract($data, 'Comment', $v['caption']);
// fetch GPS coordinates
diff --git a/Controller/Component/FileCacheComponent.php b/Controller/Component/FileCacheComponent.php
index ebdae848..8c6b96ff 100644
--- a/Controller/Component/FileCacheComponent.php
+++ b/Controller/Component/FileCacheComponent.php
@@ -104,7 +104,8 @@ public function getFilePath($media, $alias, $ext = 'jpg') {
* @param userId Id of the current user
* @param mediaId Id of the current image/file
*/
- public function delete(&$media) {
+ public function delete(&$media,$verbose=false) {
+ $verbose_str = array();
$mediaId = intval($media['Media']['id']);
$cacheDir = $this->getPath($media, false);
if (!$cacheDir) {
@@ -116,6 +117,7 @@ public function delete(&$media) {
$pattern = $this->getFilenamePrefix($mediaId).'.*';
$files = $folder->find($pattern);
if ($files) {
+ if($verbose) $verbose_str[] = "Delete cached files of image $mediaId";
CakeLog::debug("Delete cached files of image $mediaId");
foreach($files as $file) {
CakeLog::debug("Delete cache file '$file'");
@@ -124,8 +126,11 @@ public function delete(&$media) {
}
clearstatcache();
} else {
+
+ if($verbose) $verbose_str[] = "No cached files found for image $mediaId";
CakeLog::debug("No cached files found for image $mediaId");
}
+ if($verbose) return $verbose_str;
}
/**
diff --git a/Controller/Component/FilterManagerComponent.php b/Controller/Component/FilterManagerComponent.php
index 0bd9337d..580e0f61 100644
--- a/Controller/Component/FilterManagerComponent.php
+++ b/Controller/Component/FilterManagerComponent.php
@@ -308,6 +308,7 @@ public function readFiles($files, $options = array()) {
}
}
}
+
CakeLog::debug("Found ".count($stack)." files to import");
$extStack = $this->_sortFilesByExtension($stack);
$order = $this->_getExtensionsByPriority();
@@ -333,6 +334,8 @@ public function readFiles($files, $options = array()) {
$importLog = $this->_importlog($importLog, $file);
}
}
+
+
return $result;
}
@@ -450,6 +453,7 @@ public function read($filename, $forceReadMeta = false) {
return false;
}
if (!$this->isSupported($filename)) {
+
CakeLog::debug("File $filename is not supported");
return false;
}
@@ -493,18 +497,24 @@ public function read($filename, $forceReadMeta = false) {
//return $media;//overload memory with 20kb for each file
return $filename;//around 0.2kb
}
- } else {
+ }
+ /**
+ * Comment this else to create media if not exists
+ */
+ /* else {
$media = false;
if ($forceReadMeta) {
//media missing, file will not be readed; force read meta only for EXISTING media;
return false;
}
}
+ */
$filter = $this->getFilterByExtension($filename);
CakeLog::debug("Read file $filename with filter ".$filter->getName());
$result = $filter->read($file, $media);
+
if (isset($result['Media']['id'])) {
return $result['Media']['id'];
}
diff --git a/Controller/Component/ImageFilterComponent.php b/Controller/Component/ImageFilterComponent.php
index d91888d0..3995eada 100644
--- a/Controller/Component/ImageFilterComponent.php
+++ b/Controller/Component/ImageFilterComponent.php
@@ -73,14 +73,43 @@ public function read(&$file, &$media = null, $options = array()) {
}
$media = $this->controller->Media->addDefaultAcl($media, $user);
+
+
$isNew = true;
};
+
if ($this->Exiftool->isEnabled()) {
$this->Exiftool->extractImageData($media, $meta);
} else {
$this->_extractImageDataGetId3($media, $meta);
}
+
+ if(isset($media['File']) && is_array($media['File']) && count($media['File'])>0){
+ for($if=0;$iflog(">>> File ". basename($filename) . " differs from {$media['Media']['name']} (extractImageData)", 'import');
}
@@ -103,6 +132,7 @@ public function read(&$file, &$media = null, $options = array()) {
$this->FilterManager->addError($filename, 'MediaSaveError');
return false;
}
+
if ($isNew) {
$mediaId = $this->Media->getLastInsertID();
if (!$this->controller->MyFile->setMedia($file, $mediaId)) {
@@ -116,6 +146,7 @@ public function read(&$file, &$media = null, $options = array()) {
} else {
CakeLog::debug("Updated media (id ".$media['Media']['id'].")");
}
+
$this->controller->MyFile->updateReaded($file);
$this->controller->MyFile->setFlag($file, FILE_FLAG_DEPENDENT);
@@ -201,6 +232,9 @@ private function _extractImageDataGetId3(&$media, &$data) {
$v['shutter'] = $this->_computeSutter($this->_extract($data, 'jpg/exif/EXIF/ShutterSpeedValue', null));
$v['model'] = $this->_extract($data, 'jpg/exif/IFD0/Model', null);
$v['iso'] = $this->_extract($data, 'jpg/exif/EXIF/ISOSpeedRatings', null);
+ if(is_array($v['iso'])){
+ $v['iso'] = null;
+ }
//CakeLog::debug($data);
// fetch GPS coordinates
diff --git a/Controller/Component/ImageResizerComponent.php b/Controller/Component/ImageResizerComponent.php
index c387fdf6..f4d1787b 100644
--- a/Controller/Component/ImageResizerComponent.php
+++ b/Controller/Component/ImageResizerComponent.php
@@ -54,6 +54,7 @@ public function resize($src, $dst, $options = array()) {
'clearMetaData' => true,
'isOriginal' => false
), $options);
+
if (!is_readable($src)) {
CakeLog::error("Could not read source $src");
@@ -68,6 +69,7 @@ public function resize($src, $dst, $options = array()) {
$options['width'] = $size[0];
$options['height'] = $size[1];
}
+
$phpThumb = new phpThumb();
$this->_configurePhpThump($phpThumb, $src, $dst, $options);
@@ -82,8 +84,11 @@ public function resize($src, $dst, $options = array()) {
if ($this->_semaphoreId) {
sem_release($this->_semaphoreId);
}
+
+
if ($result) {
CakeLog::debug("Render {$options['size']}x{$options['size']} image in ".round($t2-$t1, 4)."ms to '{$phpThumb->cache_filename}'");
+
$phpThumb->RenderToFile($phpThumb->cache_filename);
} else {
CakeLog::error("Could not generate thumbnail: ".$phpThumb->error);
@@ -91,6 +96,19 @@ public function resize($src, $dst, $options = array()) {
die('Failed: '.$phpThumb->error);
}
+
+ /**
+ * We add watermark to the image (if satisfy the conditions) if not an
+ * original/required image. An original/required image must be a base image.
+ */
+ if((!isset($options['isOriginal']) || $options['isOriginal'] != true) &&
+ (!isset($options['isRequired']) || $options['isRequired'] != true)) {
+ $this->_addWatermark($phpThumb->cache_filename);
+ }
+
+
+
+
if ($options['clearMetaData']) {
$this->Exiftool->clearMetaData($dst);
}
@@ -103,6 +121,89 @@ public function resize($src, $dst, $options = array()) {
$this->controller->getEventManager()->dispatch($event);
return !$event->isStopped();
}
+
+
+ /**
+ * We add _addWatermark function based on Video's _addWatermark function.
+ * We looking for it in webroot.DS.img.DS.watermark folder if exists a
+ * watermark with name like 'XXXXXXX_{minsize}.jpg' when {minsize} is smaller
+ * than the size of resize file. If we found several valid image, the winner
+ * image is the image with more {minsize}.
+ */
+ private function _addWatermark($originalFile){
+ /**
+ * Code to custom watermark to each user
+ */
+ /**
+ * CODE 1
+ ** if(method_exists($this->controller->Media, 'getAPIUser')){
+ ** $accessUser = $this->controller->Media->getAPIUser();
+ ** } else {
+ ** $accessUser = $this->controller->getUser();
+ ** }
+ ** $homeDir = Configure::read('user.home.dir');
+ ** $watermarkDir = $homeDir . $accessUser['User']['id'] . DS . 'watermark';
+ */
+
+
+ /** CODE 2 **/
+ $watermarkDir = APP . 'webroot' . DS . 'img' . DS . 'watermark';
+
+ /** FIN_CODE 2 **/
+
+
+ if(file_exists($watermarkDir) && is_dir($watermarkDir)){
+ $d=opendir($watermarkDir);
+ $sizeFiles = array();
+ while($file = readdir($d)){ // no recursive, only files in this folder
+ if($file != "." AND $file!=".."){
+ $filePath = $watermarkDir . DS. $file;
+ if (is_file($filePath) && strpos(mime_content_type($filePath), 'image')!==false ){
+ // is a file and mime content is image.
+ $filePathInfo = pathinfo($filePath);
+ $fileName = $filePathInfo['filename'];
+ $lastUnderscore = strrpos($fileName, '_');
+ // the filename must be xxxxx_{minSize}.extension
+ // minSize is the min width to add the watermark
+ if($lastUnderscore!==false){
+ $sizeMinFile = (int)substr($fileName, $lastUnderscore+1);
+ $sizeFiles[$sizeMinFile] = $filePath;
+ // sample: $sizeFiles[500] = /tmp/file_500.jpeg
+ }
+ }
+ }
+ }
+
+ if(count($sizeFiles)>0){
+ ksort($sizeFiles);
+ list($imgWidth, $imgHeight, $imgType, $imgAttr) = getimagesize($originalFile);
+ $watermarkFile = false;
+ // if widthImg is less than the watermark with the minimum size,
+ // no add watermark to image.
+ //echo $imgWidth;exit;
+ foreach($sizeFiles as $ksf=>$vsf){
+ if($ksf <= $imgWidth){
+ $watermarkFile = $vsf;
+ } else {
+ break;
+ }
+ }
+ // add the watermark with the maximum size than be less than original image width.
+ if($watermarkFile){
+ App::uses('WatermarkCreator', 'Lib');
+ $watermark = new WatermarkCreator();
+ $scaleMode = 'none';
+ $position = 'se'; // southeast
+ if (!$watermark->create($originalFile, $watermarkFile, $scaleMode, $position)) {
+ CakeLog::error(join(', ', $watermark->errors));
+ }
+ }
+
+ }
+
+ }
+ }
+
/**
* Configure phpThumb with source, destination and all options
@@ -126,8 +227,20 @@ private function _configurePhpThump(&$phpThumb, &$src, &$dst, &$options) {
* @param array $options
*/
private function _configureOptions(&$phpThumb, &$options) {
+ /**
+ * Add more options params: w, h and zc
+ */
$phpThumb->w = $options['size'];
$phpThumb->h = $options['size'];
+
+ if(isset($options['w'])){ // add w
+ $phpThumb->w = $options['w'];
+ }
+
+ if(isset($options['h'])){ // add h
+ $phpThumb->h = $options['h'];
+ }
+
$phpThumb->q = $options['quality'];
$phpThumb->ra = $options['rotation'];
@@ -136,6 +249,14 @@ private function _configureOptions(&$phpThumb, &$options) {
$phpThumb->w = $options['size'];
$phpThumb->h = $options['size'];
}
+
+ if(isset($options['zc'])){ // add zc
+ $phpThumb->zc = $options['zc'];
+ }
+
+
+
+
}
/**
diff --git a/Controller/Component/MenuComponent.php b/Controller/Component/MenuComponent.php
index 1b37e7ba..5bb7ebbc 100644
--- a/Controller/Component/MenuComponent.php
+++ b/Controller/Component/MenuComponent.php
@@ -54,6 +54,9 @@ public function setBasicMainMenu() {
}
$this->addItem($text, array('controller' => $ctrl, 'admin' => false, 'action' => 'index'), $options);
}
+ $controllers['logout'] = __("Logout");
+
+ $this->addItem(__("Logout"), array('controller' => 'users', 'admin' => false, 'action' => 'logout'), array('id' => 'item-logout', 'active' => false));
}
public function beforeRender(Controller $controller) {
diff --git a/Controller/Component/PreviewManagerComponent.php b/Controller/Component/PreviewManagerComponent.php
index 12b3ad4f..0b986a5f 100644
--- a/Controller/Component/PreviewManagerComponent.php
+++ b/Controller/Component/PreviewManagerComponent.php
@@ -95,13 +95,21 @@ public function _getImageSoureFilename($media) {
* @param config (Optional) configuration for the preview generation
* @return Full path to the preview file
*/
- public function getPreview(&$media, $name, $config = array()) {
+ public function getPreview(&$media, $name, $config = array(), $paramsHash = '') {
+
+ /**
+ * Add $paramHash param to add this param to cache name file
+ */
+
$config = am($this->defaults, $config);
if (isset($this->config[$name])) {
$config = am($config, $this->config[$name]);
}
+
if ($config['requires']) {
- $src = $this->getPreview($media, $config['requires']);
+
+ // add param isRequired to not add watermark to required file
+ $src = $this->getPreview($media, $config['requires'],array('isRequired' => true));
if (!$src) {
CakeLog::error("Could not get preview of {$config['requires']}");
return false;
@@ -112,20 +120,44 @@ public function getPreview(&$media, $name, $config = array()) {
$config['rotation'] = $this->controller->Media->getRotationInDegree($media);
$config['isOriginal'] = true;
}
+
+
+ /**
+ * Change the name to create a own cache file with resize param.
+ */
+ if($paramsHash != ''){
+ $name = $name.'_'.$paramsHash;
+
+ } elseif(!isset($config['isOriginal']) && !isset($config['isRequired'])) {
+ $name = $name.'_wm';
+
+ }
+
+
$dst = $this->FileCache->getFilePath($media, $name);
if (!$dst) {
CakeLog::error("Could not get cache file path for media {$this->controller->Media->toString($media)}");
return false;
}
-
- if (file_exists($dst) && !$config['force']) {
- if (is_readable($dst)) {
+
+
+ if (file_exists($dst) && !$config['force']) {
+ /**
+ * If dst file is modified a hour ago, delete and create it again.
+ * Expiretime value should be a config value.
+ */
+ $expireTime = 3600;
+ if(filemtime($dst) < (time()-$expireTime)){
+ $this->FileCache->delete($media);
+ } elseif (is_readable($dst)) {
return $dst;
} else {
CakeLog::error("Cachefile not readable: $dst");
return false;
}
}
+
+ // creo imagen original
$this->controller->loadComponent('ImageResizer', $this);
if (!$this->ImageResizer->resize($src, $dst, $config)) {
CakeLog::error("Resize of '$src' to '$dst' failed");
@@ -134,4 +166,6 @@ public function getPreview(&$media, $name, $config = array()) {
}
return $dst;
}
+
+
}
\ No newline at end of file
diff --git a/Controller/Component/QueryBuilderComponent.php b/Controller/Component/QueryBuilderComponent.php
index 4fe5ce9e..cd8835b1 100644
--- a/Controller/Component/QueryBuilderComponent.php
+++ b/Controller/Component/QueryBuilderComponent.php
@@ -641,7 +641,7 @@ private function _mapParams(&$data) {
public function build($data, $defaults) {
$this->counter = 0;
$data = $this->_mapParams($data);
- $defaults = am(array('sort' => 'id', 'show' => EXPLORER_DEFAULT_SHOW, 'page' => 1), (array) $defaults);
+ $defaults = am(array('sort' => 'top', 'show' => EXPLORER_DEFAULT_SHOW, 'page' => 1), (array) $defaults);
list($required, $exclude) = $this->_splitRequirements($data);
// if we have some required conditions default operand is OR for optional conditions
$defaultOperand = $required ? 'ANY' : 'AND';
@@ -720,6 +720,11 @@ private function _buildOrder(&$data, &$query, &$defaults) {
case 'name': $query['order'][] = 'Media.name'; break;
case '-name': $query['order'][] = 'Media.name DESC'; break;
case 'id': $query['order'][] = 'Media.id'; break;
+ case 'top': $query['order'][] = "Media.id IN
+(SELECT MediaTop.media_id FROM `fields_media` as `MediaTop` INNER JOIN `fields` as `FieldsTop`
+ON MediaTop.field_id = FieldsTop.id
+WHERE (FieldsTop.data = 'top' AND FieldsTop.name = 'keyword')
+) DESC, Media.name ASC";break;
default:
CakeLog::error("Unknown sort value: {$sort}. Use default sort order");
$query['order'][] = 'Media.date DESC, Media.id';
@@ -729,6 +734,7 @@ private function _buildOrder(&$data, &$query, &$defaults) {
if ($sort != 'random' && $sort != 'id') {
$query['order'][] = 'Media.id';
}
+
}
/**
diff --git a/Controller/Component/SearchComponent.php b/Controller/Component/SearchComponent.php
index f196c91b..efaea281 100644
--- a/Controller/Component/SearchComponent.php
+++ b/Controller/Component/SearchComponent.php
@@ -58,7 +58,7 @@ class SearchComponent extends Component
'pos' => array('numericRule' => 'numeric', 'minRule' => array('rule' => array('comparison', '>=', 1))),
'similar' => array('rule' => array('maxLength', 30), 'multiple' => true),
'show' => array('numericRule' => 'numeric', 'minRule' => array('rule' => array('comparison', '>=', 1)), 'maxRule' => array('rule' => array('comparison', '<=', 240))),
- 'sort' => array('rule' => array('inList', array('date', '-date', 'newest', 'changes', 'viewed', 'popularity', 'random', 'name'))),
+ 'sort' => array('rule' => array('inList', array('date', '-date', 'newest', 'changes', 'viewed', 'popularity', 'random', 'name', 'top'))),
'south' => array('rule' => array('custom', '/-?\d+(\.\d+)?/')),
'sublocation' => array('rule' => array('maxLength', 30), 'multiple' => true),
'state' => array('rule' => array('maxLength', 30), 'multiple' => true),
@@ -546,11 +546,46 @@ public function paginateByCrumbs($crumbs) {
$tmp = $this->getParams();
$this->clear();
$this->_getParameterFromCrumbs($crumbs);
- $data = $this->paginate();
+ $data = $this->paginate();
+
$this->setParams($tmp);
return $data;
}
+ /**
+ * We return allResults with no paginate
+ */
+ public function allResults($crumbs,$onlyCount=false){
+
+ $this->_getParameterFromCrumbs($crumbs);
+
+ $this->setParam('sort', 'top');
+ $query = $this->QueryBuilder->build($this->getParams(), $this->defaults);
+ $tmp = $query;
+ unset($query['limit']);
+ unset($query['page']);
+ // Ensure only unique Media ids are counted
+ // $query['fields'] = 'DISTINCT Media.id';
+ $query['recursive'] = -1;
+ unset($query['group']);
+
+
+ if($onlyCount) $search = 'count';
+ else $search = 'all';
+ $data = $this->controller->Media->find($search, $query);
+
+ return $data;
+
+ }
+ private function _getCacheHash($arr = array('')){
+ if(is_array($arr) && count($arr)>0){
+ return md5(serialize($arr));
+ } else {
+ return false;
+ }
+ }
+
+
public function paginate() {
$query = $this->QueryBuilder->build($this->getParams(), $this->defaults);
$tmp = $query;
@@ -560,7 +595,9 @@ public function paginate() {
$query['fields'] = 'DISTINCT Media.id';
$query['recursive'] = -1;
unset($query['group']);
+
$count = $this->controller->Media->find('count', $query);
+
$query = $tmp;
$params = array(
@@ -574,6 +611,8 @@ public function paginate() {
'data' => $this->getParams()
);
+
+
if ($count == 0) {
$this->controller->request->params['search'] = $params;
return array();
@@ -594,6 +633,8 @@ public function paginate() {
// get all media and set access flags
$this->controller->Media->bindModel(array('hasMany' => array('GroupsMedia' => array())));
+
+
$data = $this->controller->Media->find('all', $query);
$user = $this->controller->getUser();
$groupIds = $this->controller->User->getAclGroupIds($user);
diff --git a/Controller/ExplorerController.php b/Controller/ExplorerController.php
index 8ce2f0da..cd7f8ea4 100644
--- a/Controller/ExplorerController.php
+++ b/Controller/ExplorerController.php
@@ -737,6 +737,8 @@ public function selection($action) {
$this->render('index');
}
+
+
public function sync($id) {
if (!$this->RequestHandler->isAjax() || !$this->RequestHandler->isPost()) {
@@ -781,9 +783,46 @@ public function media() {
if (Configure::read('debug') > 1) {
Configure::write('debug', 1);
}
+
+
$this->request->data = $this->Search->paginateByCrumbs($this->crumbs);
}
+ public function count(){
+ // return the count
+ $this->layout = 'bare';
+ if (Configure::read('debug') > 1) {
+ Configure::write('debug', 1);
+ }
+
+
+ $this->request->data = $this->Search->allResults($this->crumbs, true);
+
+
+ }
+
+ public function getids(){
+ // return the count
+ if (Configure::read('debug') > 1) {
+ Configure::write('debug', 1);
+ }
+
+ $ids = array();
+ $this->request->data = $this->Search->allResults($this->crumbs);
+ if(count($this->request->data)>0){
+ for($i=0;$irequest->data);$i++){
+ $ids[$i] = $this->request->data[$i]['Media']['id'];
+ }
+ echo json_encode($ids);
+ } else {
+ echo json_encode(array());
+
+ }
+ exit;
+
+
+ }
+
public function points($north, $south, $west, $east) {
$this->Search->setSort('random');
diff --git a/Controller/MediaController.php b/Controller/MediaController.php
index 71d6dc92..191e7218 100644
--- a/Controller/MediaController.php
+++ b/Controller/MediaController.php
@@ -22,8 +22,8 @@ class MediaController extends AppController
var $config = array(
'video' => array('size' => OUTPUT_SIZE_VIDEO, 'bitrate' => OUTPUT_BITRATE_VIDEO)
);
- var $components = array('PreviewManager');
+ var $components = array('PreviewManager','Search','FileCache'); // add components Search and Filecache
public function beforeFilter() {
// Reduce security level for this controller if required. Security level
// 'high' allows only 10 concurrent requests
@@ -91,8 +91,12 @@ private function _handleClientCache($filename) {
* @return Media model data. If no media is found or access is denied it
* responses 404
*/
- private function _getMedia($id, $type = 'preview') {
- $user = $this->getUser();
+ private function _getMedia($id, $type = 'preview',$notFoundReturn=false) {
+
+ // if the param API is set, the access user will be the user with that API key.
+ // if not, the user will be the login user
+ $user = $this->Media->getAPIUser();
+ if(!$user) $user = $this->getUser();
switch ($type) {
case 'hd':
$flag = ACL_READ_ORIGINAL; break;
@@ -107,15 +111,19 @@ private function _getMedia($id, $type = 'preview') {
$media = $this->Media->find('first', $query);
if (!$media) {
CakeLog::debug("Media not found or access denied for media $id");
+ if($notFoundReturn) return false;
+ // sometimes we want return a false and not a redirect when not media found
$this->redirect(null, 403);
}
return $media;
}
- private function _sendPreview($id, $type) {
+ private function _sendPreview($id, $type,$options=array(),$paramsHash='') {
+ // add the param options
+ // and the param paramHash
$media = $this->_getMedia($id, $type);
- $preview = $this->PreviewManager->getPreview($media, $type);
+ $preview = $this->PreviewManager->getPreview($media, $type, $options,$paramsHash);
if (!$preview) {
CakeLog::error("Fetching preview type '{$type}' for {$this->Media->toString($media)} failed");
$this->redirect(null, 403);
@@ -145,23 +153,37 @@ private function _createFlashVideo($id) {
}
public function mini($id) {
- return $this->_sendPreview($id, 'mini');
+
+ return $this->_sendImage('mini', $id);
}
public function thumb($id) {
- return $this->_sendPreview($id, 'thumb');
+
+ return $this->_sendImage('thumb', $id);
}
public function preview($id) {
- return $this->_sendPreview($id, 'preview');
+ return $this->_sendImage('preview', $id);
}
public function high($id) {
- return $this->_sendPreview($id, 'high');
+ return $this->_sendImage('high', $id);
}
public function hd($id) {
- return $this->_sendPreview($id, 'hd');
+ return $this->_sendImage('hd', $id);
+ }
+
+ private function _sendImage($type, $id){
+
+ // pass the resize params and string param to create the resize image
+
+ $params = $this->_getParamsResize();
+ if($params){
+ return $this->_sendPreview($id, $type,$params['arr'], $params['str']);
+ } else {
+ return $this->_sendPreview($id, $type);
+ }
}
public function video($id) {
@@ -169,6 +191,8 @@ public function video($id) {
$this->response->file($filename, array('download' => true));
return $this->response;
}
+
+
public function file($id) {
$id = intval($id);
@@ -332,4 +356,152 @@ public function zip($format) {
$zipName = 'phtagr-' . date('Y-m-d_H-i-s') . '.zip';
$this->_createZipFile($zipName, $files);
}
+
+ /**
+
+ * $number is the position of the image into the search what we want to show
+ */
+ public function show($number){
+ $medias = $this->_getListPhotos();
+ $number = ($number>0) ? $number-1 : 0;
+
+ $name = 'high';
+ if(isset($medias[$number])){
+ $params = $this->_getParamsResize();
+ //$name = ($params['str'] != '') ? $name.'_'.$params['str'] : $name;
+ return $this->_sendPreview($medias[$number]['Media']['id'], $name,$params['arr'],$params['str']);
+ } else {
+ return $this->_sendPreview(null,$name);
+ }
+ }
+
+ public function clean($number){
+ /**
+ * If contains params, clean the position $number in search array
+ * If not, clean the $number ID
+ */
+
+ $this->crumbs = $this->Search->urlToCrumbs($this->request->url, 2);
+ if(count($this->crumbs)>0){
+ $medias = $this->_getListPhotos();
+ if($number == 0){
+ $allMedias = true;
+ } else {
+ $number = ($number>0) ? $number-1 : 0;
+ if(isset($medias[$number])){
+ $media = $medias[$number];
+ } else {
+ //$media = null;
+ }
+ }
+ } else {
+ $media = $this->_getMedia($number,'preview',true);
+
+ }
+
+ $delete = array();
+ if(isset($media) && is_array($media)){
+ $delete[] = array('name' => $media['name'],
+ 'msg' => $this->FileCache->delete($media, true));
+
+ } elseif(isset($allMedias) && isset($medias)){
+ foreach($medias as $media){
+ $delete[] = array('name' => $media['Media']['name'],
+ 'msg' =>$this->FileCache->delete($media,true));
+ }
+ }
+
+ $this->layout = 'default';
+ $this->request->data = $delete;
+
+
+ }
+
+
+
+
+ /**
+ * add function getListPhotos
+ */
+ private function _getListPhotos(){
+ $this->crumbs = $this->Search->urlToCrumbs($this->request->url, 2);
+ #echo 'hola';exit;
+ return $this->Search->allResults($this->crumbs);
+
+ }
+
+ /**
+ * resize params, return an string and an array.
+ */
+
+ private function _getParamsResize(){
+ if(!$this->crumbs) $this->crumbs = $this->Search->urlToCrumbs($this->request->url, 2);
+ #echo 'hola';
+ #print_r($this->crumbs);exit;
+ $arrParams = array();
+
+ foreach($this->crumbs as $crumb){
+ list($crumbkey, $crumbvalue) = explode(':', $crumb,2);
+ switch($crumbkey){
+ case 'size':
+ $arrParams['w'] = (int)$crumbvalue;
+ $arrParams['h'] = (int)$crumbvalue;
+ case 'square':
+ $arrParams['zc'] = 1;
+ break;
+ case 'w':
+ case 'h':
+ case 'zc':
+ case 'quality':
+ case 'rotation':
+ $arrParams[$crumbkey] = $crumbvalue;
+ break;
+
+ }
+ }
+
+ if(count($arrParams) == 0){
+ //if($mode == 'str' || $mode == 'all') $strParams = '';
+ foreach(array('size', 'square', 'w','h','zc','quality','rotation') as $p){
+ if(isset($this->request->query[$p])){
+ $param = $this->request->query[$p];
+ switch($p){
+ case 'size':
+ $arrParams['w'] = (int)$param;
+ $arrParams['h'] = (int)$param;
+ break;
+ case 'square':
+ $arrParams['zc'] = 1;
+ break;
+ case 'w':
+ case 'h':
+ case 'zc':
+ case 'quality':
+ case 'rotation':
+ $arrParams[$p] = $param;
+ break;
+ }
+ }
+ }
+ }
+
+ if(count($arrParams)>0){
+
+ $strParams = '';
+ foreach($arrParams as $kaP=>$vaP){
+ if($kaP == 'quality') $kaP = 'q';
+ elseif($kaP == 'rotation') $kaP = 'r';
+ $strParams .= "{$kaP}{$vaP}";
+ }
+ return array('str' => $strParams, 'arr' => $arrParams);
+ } else {
+ return false;
+ }
+
+
+ return $arrParams;
+ }
+
+
+
}
diff --git a/Controller/OptionsController.php b/Controller/OptionsController.php
index 94df38f2..8851ab43 100644
--- a/Controller/OptionsController.php
+++ b/Controller/OptionsController.php
@@ -60,7 +60,7 @@ public function profile() {
$userId = $this->getUserId();
if (!empty($this->request->data)) {
$this->User->id = $userId;
- if (!$this->User->save($this->request->data['User'], true, array('username', 'firstname', 'lastname', 'email', 'visible_level', 'notify_interval'))) {
+ if (!$this->User->save($this->request->data['User'], true, array('username', 'firstname', 'lastname', 'email', 'key', 'visible_level', 'notify_interval'))) {
CakeLog::error("Could not update user profile");
$this->Session->setFlash(__("Could not save profile!"));
} else {
diff --git a/Model/Field.php b/Model/Field.php
index a1c3a0c2..5c22ae35 100644
--- a/Model/Field.php
+++ b/Model/Field.php
@@ -104,9 +104,33 @@ public function createFields(&$media) {
* @return array Field assignments
*/
public function editSingle(&$media, &$data, $onlyFields = null) {
- if (empty($data['Field'])) {
+
+ if (empty($data['Field'])) {
return array();
}
+
+ /*
+ $tags_key = array();
+ if(isset($media['File']) && is_array($media['File']) && count($media['File'])>0){
+ for($if=0;$ifUser->findByKey($_GET['api']);
+ }
+
+ if(isset($hashUser['User']) && $hashUser['User']['id'] != -1) return $hashUser;
+ else return false;
+ }
/**
* Build ACL query for media.
*
@@ -556,6 +565,8 @@ public function buildAclJoin($alias) {
* @return returns ACL query
*/
public function buildAclQuery($user, $userId = 0, $level = ACL_READ_PREVIEW) {
+ $hashUser = $this->getAPIUser();
+ if($hashUser !== false) $user = $hashUser;
$level = intval($level);
$conditions = array();
$joins = array();
@@ -1062,6 +1073,7 @@ public function editSingle(&$media, &$data, &$user) {
if (!isset($media['Media']['canWriteMeta'])) {
$this->setAccessFlags($media, $user);
}
+
// handle fields
if ($media['Media']['canWriteCaption']) {
$tmp = am($this->Field->editSingle($media, $data), $tmp);
@@ -1203,4 +1215,30 @@ public function deleteGroupByUser(&$group, &$user) {
$result = $this->query($sql);
return is_array($result) && !count($result);
}
-}
\ No newline at end of file
+
+ // Cached queries
+ public function find($type = 'first', $query = array()){
+ /*
+ $cacheInFind = true;
+
+ if($cacheInFind){
+ $cacheHash = md5(serialize(array_merge(array('type' => $type),$query)));
+ $data = Cache::read($cacheHash, '_cake_db_');
+
+ if(!$data){
+ $data = parent::find($type,$query);
+ Cache::write($cacheHash, $data, '_cake_db_');
+ }
+
+ return $data;
+ } else {
+ return parent::find($type,$query);
+ }
+
+ */
+ return parent::find($type,$query);
+
+
+ }
+}
+
diff --git a/Vendor/getid3/module.graphic.jpg.php b/Vendor/getid3/module.graphic.jpg.php
index 5663a2f5..69a435dd 100644
--- a/Vendor/getid3/module.graphic.jpg.php
+++ b/Vendor/getid3/module.graphic.jpg.php
@@ -66,7 +66,7 @@ public function Analyze() {
if (substr($imageinfo['APP1'], 0, 4) == 'Exif') {
//$info['warning'][] = 'known issue: https://bugs.php.net/bug.php?id=62523';
//return false;
- $info['jpg']['exif'] = exif_read_data($info['filenamepath'], null, true, false);
+ $info['jpg']['exif'] = @exif_read_data($info['filenamepath'], null, true, false);
} else {
$info['warning'][] = 'exif_read_data() cannot parse non-EXIF data in APP1 (expected "Exif", found "'.substr($imageinfo['APP1'], 0, 4).'")';
}
diff --git a/Vendor/phpthumb/phpthumb.class.php b/Vendor/phpthumb/phpthumb.class.php
index b3f9a8a8..41d4b5fc 100644
--- a/Vendor/phpthumb/phpthumb.class.php
+++ b/Vendor/phpthumb/phpthumb.class.php
@@ -347,7 +347,7 @@ function GenerateThumbnail() {
$this->phpThumbDebug('8g');
$this->CreateGDoutput();
$this->phpThumbDebug('8h');
-
+
switch ($this->far) {
case 'L':
case 'TL':
@@ -1303,7 +1303,7 @@ function ImageMagickThumbnailToGD() {
// $UnAllowedParameters contains options that can only be processed in GD, not ImageMagick
// note: 'fltr' *may* need to be processed by GD, but we'll check that in more detail below
$UnAllowedParameters = array('xto', 'ar', 'bg', 'bc');
- // 'ra' may be part of this list, if not a multiple of 90°
+ // 'ra' may be part of this list, if not a multiple of 90�
foreach ($UnAllowedParameters as $parameter) {
if (isset($this->$parameter)) {
$this->DebugMessage('$this->useRawIMoutput=false because "'.$parameter.'" is set', __FILE__, __LINE__);
@@ -3398,7 +3398,6 @@ function SourceImageToGD() {
return true;
}
$this->DebugMessage('starting SourceImageToGD()', __FILE__, __LINE__);
-
if ($this->config_prefer_imagemagick) {
if (empty($this->sourceFilename) && !empty($this->rawImageData)) {
$this->DebugMessage('Copying raw image data to temp file and trying again with ImageMagick', __FILE__, __LINE__);
diff --git a/View/Elements/Explorer/menu.ctp b/View/Elements/Explorer/menu.ctp
index ed84a1f7..b27af1b7 100644
--- a/View/Elements/Explorer/menu.ctp
+++ b/View/Elements/Explorer/menu.ctp
@@ -113,6 +113,7 @@
$links[] = $this->Html->link(__('modified'), $this->Breadcrumb->crumbUrl($this->Breadcrumb->replace($crumbs, 'sort', 'changes')));
$links[] = $this->Html->link(__('view count'), $this->Breadcrumb->crumbUrl($this->Breadcrumb->replace($crumbs, 'sort', 'viewed')));
$links[] = $this->Html->link(__('random'), $this->Breadcrumb->crumbUrl($this->Breadcrumb->replace($crumbs, 'sort', 'random')));
+ $links[] = $this->Html->link(__('top'), $this->Breadcrumb->crumbUrl($this->Breadcrumb->replace($crumbs, 'sort', 'top')));
echo implode(' ', $links);
?>
diff --git a/View/Explorer/count.ctp b/View/Explorer/count.ctp
new file mode 100644
index 00000000..2effd814
--- /dev/null
+++ b/View/Explorer/count.ctp
@@ -0,0 +1,2 @@
+request->data;
\ No newline at end of file
diff --git a/View/Explorer/media.ctp b/View/Explorer/media.ctp
index 3475fba7..68a4076e 100644
--- a/View/Explorer/media.ctp
+++ b/View/Explorer/media.ctp
@@ -53,6 +53,10 @@
$contentUrl = sprintf("/media/preview/%d%s/%s", $media['Media']['id'], $keyParam, $media['Media']['name']);
$previewSize = $this->ImageData->getimagesize($media, OUTPUT_SIZE_PREVIEW);
}
+ if(isset($_GET['api']) && $_GET['api']!=''){
+ $thumbUrl.='?api='.$_GET['api'];
+ $contentUrl.='?api='.$_GET['api'];
+ }
?> type="image/jpeg" />
type="image/jpeg" />
ImageData->getPathLink($file);
$files[] = $this->Html->link($file['file'], $link).' ('.$this->Number->toReadableSize($file['size']).')';
}
+ $preview = '/media/preview/'.$this->request->data['Media']['id'];
$cells[] = array(__("File(s)"), implode(', ', $files));
+ $cells[] = array(__("Preview"), $this->Html->link($this->request->data['Media']['id'],$preview));
}
$folders = $this->ImageData->getFolderLinks($this->request->data);
if ($folders) {
diff --git a/View/Layouts/default.ctp b/View/Layouts/default.ctp
index 54648c03..9f4dca10 100644
--- a/View/Layouts/default.ctp
+++ b/View/Layouts/default.ctp
@@ -26,6 +26,11 @@
Menu->menu('top-menu'); ?>
+params['controller'] == 'users' && $this->params['action'] == 'login')
+ || $this->params['controller'] == 'setup'
+ || $currentUser['User']['id']>0): ?>
+
Menu->menu('main-menu'); ?>
@@ -51,5 +56,7 @@
Html->link(__("phTagr.org"), 'http://www.phtagr.org')); ?>
+
+