Added Tagging, Moving with Replace, Optimised Delete
This commit is contained in:
parent
c88d289e82
commit
08f823460e
@ -33,8 +33,7 @@ class Controller_Photo extends Controller_TemplateDefault {
|
|||||||
$output .= sprintf('Removing %s (%s)',$po->id,$po->file_path());
|
$output .= sprintf('Removing %s (%s)',$po->id,$po->file_path());
|
||||||
|
|
||||||
// Delete it
|
// Delete it
|
||||||
if (unlink($po->file_path()))
|
$po->delete();
|
||||||
$po->delete();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$p = ORM::factory('Photo');
|
$p = ORM::factory('Photo');
|
||||||
@ -167,6 +166,7 @@ class Controller_Photo extends Controller_TemplateDefault {
|
|||||||
foreach (array(
|
foreach (array(
|
||||||
'ID'=>array('key'=>'id','value'=>HTML::anchor('/photo/details/%VALUE%','%VALUE%')),
|
'ID'=>array('key'=>'id','value'=>HTML::anchor('/photo/details/%VALUE%','%VALUE%')),
|
||||||
'Thumbnail'=>array('key'=>'id','value'=>HTML::anchor('/photo/view/%VALUE%',HTML::image('photo/thumbnail/%VALUE%'))),
|
'Thumbnail'=>array('key'=>'id','value'=>HTML::anchor('/photo/view/%VALUE%',HTML::image('photo/thumbnail/%VALUE%'))),
|
||||||
|
'ThumbSig'=>array('key'=>'thumbnail_sig()'),
|
||||||
'Signature'=>array('key'=>'signature'),
|
'Signature'=>array('key'=>'signature'),
|
||||||
'Date Taken'=>array('key'=>'date_taken()'),
|
'Date Taken'=>array('key'=>'date_taken()'),
|
||||||
'File Modified'=>array('key'=>'date_file("m",TRUE)'),
|
'File Modified'=>array('key'=>'date_file("m",TRUE)'),
|
||||||
|
@ -15,7 +15,10 @@ class Model_Photo extends ORM {
|
|||||||
|
|
||||||
protected $_has_many = array(
|
protected $_has_many = array(
|
||||||
'album'=>array('through'=>'album_photo'),
|
'album'=>array('through'=>'album_photo'),
|
||||||
'people'=>array('through'=>'people_photo','far_key'=>'people_id'),
|
'people'=>array('through'=>'photo_people','far_key'=>'people_id'),
|
||||||
|
'tags'=>array('through'=>'photo_tag','far_key'=>'tag_id'),
|
||||||
|
'photo_tag'=>array('far_key'=>'id'),
|
||||||
|
'photo_people'=>array('far_key'=>'id'),
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -65,6 +68,27 @@ class Model_Photo extends ORM {
|
|||||||
return trim(chunk_split(sprintf("%0{$depth}s",$this->id),$sep,'/'),'/');
|
return trim(chunk_split(sprintf("%0{$depth}s",$this->id),$sep,'/'),'/');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function file_path_short($path) {
|
||||||
|
return preg_replace(":^{$this->_path}".DIRECTORY_SEPARATOR.":",'',$path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function delete() {
|
||||||
|
if (unlink($this->file_path())) {
|
||||||
|
// Remove any tags
|
||||||
|
foreach ($this->photo_tag->find_all() as $o)
|
||||||
|
$o->delete();
|
||||||
|
|
||||||
|
// Remove any people
|
||||||
|
foreach ($this->photo_people->find_all() as $o)
|
||||||
|
$o->delete();
|
||||||
|
|
||||||
|
return parent::delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
// If unlink failed...
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
public function file_size() {
|
public function file_size() {
|
||||||
return filesize($this->file_path());
|
return filesize($this->file_path());
|
||||||
}
|
}
|
||||||
@ -121,15 +145,22 @@ class Model_Photo extends ORM {
|
|||||||
if (! $path)
|
if (! $path)
|
||||||
$path = $this->file_path(FALSE,TRUE);
|
$path = $this->file_path(FALSE,TRUE);
|
||||||
|
|
||||||
$po = ORM::factory('Photo',$path);
|
// Check if there is already a phoot here - and if it is pending delete.
|
||||||
|
$po = ORM::factory('Photo',array('filename'=>$this->file_path_short($path)));
|
||||||
|
|
||||||
// If the file already exists, we'll ignore the move.
|
// @todo Move any tags if we are replacing an existing photo.
|
||||||
if ($po->loaded() OR file_exists($path) OR ! File::ParentDirExist(dirname($path),TRUE))
|
if ($po->loaded() AND (! $po->remove OR ($po->remove AND ! $po->delete())))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
unset($po);
|
||||||
|
|
||||||
|
// If the file already exists, or we cant create the dir structure, we'll ignore the move
|
||||||
|
if (file_exists($path) OR ! File::ParentDirExist(dirname($path),TRUE))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (rename($this->file_path(),$path)) {
|
if (rename($this->file_path(),$path)) {
|
||||||
// Convert the path to a relative one.
|
// Convert the path to a relative one.
|
||||||
$this->filename = preg_replace(":^{$this->_path}/:",'',$path);
|
$this->filename = $this->file_path_short($path);
|
||||||
|
|
||||||
// If the DB update failed, move it back.
|
// If the DB update failed, move it back.
|
||||||
if (! $this->save() AND ! rename($path,$this->file_path()))
|
if (! $this->save() AND ! rename($path,$this->file_path()))
|
||||||
@ -176,11 +207,14 @@ class Model_Photo extends ORM {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function SignatureTrim($signature) {
|
public static function SignatureTrim($signature,$chars=6) {
|
||||||
return sprintf('%s...%s',substr($signature,0,6),substr($signature,-6));
|
return sprintf('%s...%s',substr($signature,0,$chars),substr($signature,-1*$chars));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function thumbnail($rotate=TRUE) {
|
public function thumbnail($rotate=TRUE) {
|
||||||
|
if (! $this->thumbnail)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
$imo = new Imagick();
|
$imo = new Imagick();
|
||||||
|
|
||||||
$imo->readImageBlob($this->thumbnail);
|
$imo->readImageBlob($this->thumbnail);
|
||||||
@ -191,6 +225,10 @@ class Model_Photo extends ORM {
|
|||||||
return $imo->getImageBlob();
|
return $imo->getImageBlob();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function thumbnail_sig() {
|
||||||
|
return md5($this->thumbnail()).':'.strlen($this->thumbnail());
|
||||||
|
}
|
||||||
|
|
||||||
public function type($mime=FALSE) {
|
public function type($mime=FALSE) {
|
||||||
return strtolower($mime ? File::mime_by_ext(pathinfo($this->filename,PATHINFO_EXTENSION)) : pathinfo($this->filename,PATHINFO_EXTENSION));
|
return strtolower($mime ? File::mime_by_ext(pathinfo($this->filename,PATHINFO_EXTENSION)) : pathinfo($this->filename,PATHINFO_EXTENSION));
|
||||||
}
|
}
|
||||||
|
14
application/classes/Model/Photo/People.php
Normal file
14
application/classes/Model/Photo/People.php
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<?php defined('SYSPATH') or die('No direct access allowed.');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class supports Tags.
|
||||||
|
*
|
||||||
|
* @package Photo
|
||||||
|
* @category Models
|
||||||
|
* @author Deon George
|
||||||
|
* @copyright (c) 2014 Deon George
|
||||||
|
* @license http://dev.leenooks.net/license.html
|
||||||
|
*/
|
||||||
|
class Model_Photo_People extends ORM {
|
||||||
|
}
|
||||||
|
?>
|
14
application/classes/Model/Photo/Tag.php
Normal file
14
application/classes/Model/Photo/Tag.php
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<?php defined('SYSPATH') or die('No direct access allowed.');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class supports Tags.
|
||||||
|
*
|
||||||
|
* @package Photo
|
||||||
|
* @category Models
|
||||||
|
* @author Deon George
|
||||||
|
* @copyright (c) 2014 Deon George
|
||||||
|
* @license http://dev.leenooks.net/license.html
|
||||||
|
*/
|
||||||
|
class Model_Photo_Tag extends ORM {
|
||||||
|
}
|
||||||
|
?>
|
14
application/classes/Model/Tags.php
Normal file
14
application/classes/Model/Tags.php
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<?php defined('SYSPATH') or die('No direct access allowed.');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class supports Tags.
|
||||||
|
*
|
||||||
|
* @package Photo
|
||||||
|
* @category Models
|
||||||
|
* @author Deon George
|
||||||
|
* @copyright (c) 2014 Deon George
|
||||||
|
* @license http://dev.leenooks.net/license.html
|
||||||
|
*/
|
||||||
|
class Model_Tags extends ORM {
|
||||||
|
}
|
||||||
|
?>
|
@ -10,74 +10,177 @@
|
|||||||
* @license http://dev.leenooks.net/license.html
|
* @license http://dev.leenooks.net/license.html
|
||||||
*/
|
*/
|
||||||
class Task_Photo_Import extends Minion_Task {
|
class Task_Photo_Import extends Minion_Task {
|
||||||
|
private $_log = '/tmp/photo_import.txt';
|
||||||
|
|
||||||
private $_accepted = array(
|
private $_accepted = array(
|
||||||
'jpg',
|
'jpg',
|
||||||
);
|
);
|
||||||
|
|
||||||
protected $_options = array(
|
protected $_options = array(
|
||||||
'file'=>NULL, // Photo File to Import
|
'dir'=>NULL, // Directory of Photos to Import
|
||||||
'verbose'=>FALSE, // Photo File to Import
|
'file'=>NULL, // Photo File to Import
|
||||||
|
'tags'=>NULL,
|
||||||
|
'people'=>NULL,
|
||||||
|
'ignoredupe'=>FALSE, // Skip duplicate photos
|
||||||
|
'deletedupe'=>FALSE, // Skip duplicate photos
|
||||||
|
'verbose'=>FALSE, // Photo File to Import
|
||||||
);
|
);
|
||||||
|
|
||||||
|
private function _adddir(&$value,$key,$path='') {
|
||||||
|
if ($path)
|
||||||
|
$value = sprintf('%s/%s',$path,$value);
|
||||||
|
}
|
||||||
|
|
||||||
protected function _execute(array $params) {
|
protected function _execute(array $params) {
|
||||||
if (is_null($params['file']))
|
$tags = NULL;
|
||||||
throw new Kohana_Exception('Missing filename, please use --file=');
|
$t = $p = array();
|
||||||
|
|
||||||
if (preg_match('/@__thumb/',$params['file']) OR preg_match('/\/._/',$params['file']))
|
if (is_null($params['file']) AND is_null($params['dir']) OR ($params['file'] AND $params['dir']))
|
||||||
return sprintf("Ignoring file [%s]\n",$params['file']);
|
throw new Kohana_Exception('Missing filename, please use --file= OR --dir=');
|
||||||
|
|
||||||
if (! in_array(strtolower(pathinfo($params['file'],PATHINFO_EXTENSION)),$this->_accepted))
|
if ($params['dir']) {
|
||||||
return sprintf("Ignoring file [%s]\n",$params['file']);
|
$files = array_diff(scandir($params['dir']),array('.','..'));
|
||||||
|
|
||||||
$po = ORM::factory('Photo',array('filename'=>$params['file']));
|
array_walk($files,'static::_adddir',$params['dir']);
|
||||||
|
|
||||||
if (! $po->loaded())
|
} else
|
||||||
$po->filename = realpath($params['file']);
|
$files = array($params['file']);
|
||||||
|
|
||||||
$po->date_taken = $this->dbcol(strtotime($po->io('exif:DateTime')));
|
// Tags
|
||||||
$po->signature = $this->dbcol($po->io()->getImageSignature());
|
if ($params['tags']) {
|
||||||
$po->make = $this->dbcol($po->io('exif:Make'));
|
$tags = explode(',',$params['tags']);
|
||||||
$po->model = $this->dbcol($po->io('exif:Model'));
|
$t = ORM::factory('Tags')->where('tag','IN',$tags)->find_all();
|
||||||
$po->height = $this->dbcol($po->io()->getImageheight());
|
|
||||||
$po->width = $this->dbcol($po->io()->getImageWidth());
|
|
||||||
$po->orientation = $this->dbcol($po->io()->getImageOrientation());
|
|
||||||
$po->subsectime = $this->dbcol($po->io('exif:SubSecTimeOriginal'));
|
|
||||||
|
|
||||||
$po->gps_lat = $this->dbcol($po->gps(preg_split('/,\s?/',$po->io()->getImageProperty('exif:GPSLatitude')),$po->io()->getImageProperty('exif:GPSLatitudeRef')));
|
|
||||||
$po->gps_lon = $this->dbcol($po->gps(preg_split('/,\s?/',$po->io()->getImageProperty('exif:GPSLongitude')),$po->io()->getImageProperty('exif:GPSLongitudeRef')));
|
|
||||||
|
|
||||||
try {
|
|
||||||
$po->thumbnail = $this->dbcol(exif_thumbnail($po->filename));
|
|
||||||
} catch (Exception $e) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ($params['verbose']) {
|
// People
|
||||||
case 1:
|
if ($params['people']) {
|
||||||
print_r($po->what_changed());
|
$tags = explode(',',$params['people']);
|
||||||
break;
|
$p = ORM::factory('People')->where('tag','IN',$tags)->find_all();
|
||||||
|
|
||||||
case 2:
|
|
||||||
print_r($po->io()->getImageProperties());
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($po->list_duplicate()->find_all()->count())
|
$c = 0;
|
||||||
$po->duplicate = '1';
|
foreach ($files as $file) {
|
||||||
|
if ($params['verbose'])
|
||||||
|
printf("Processing file [%s]\n",$file);
|
||||||
|
|
||||||
if (! $po->changed())
|
if (preg_match('/@__thumb/',$file) OR preg_match('/\/._/',$file)) {
|
||||||
return sprintf("Image [%s] already in DB: %s\n",$params['file'],$po->id);
|
$this->writelog(sprintf("Ignoring file [%s]\n",$file));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
$po->save();
|
if (! in_array(strtolower(pathinfo($file,PATHINFO_EXTENSION)),$this->_accepted)) {
|
||||||
|
$this->writelog(sprintf("Ignoring file [%s]\n",$file));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if ($po->saved())
|
$c++;
|
||||||
return sprintf("Image [%s] stored in DB: %s\n",$params['file'],$po->id);
|
|
||||||
|
|
||||||
return sprintf("Image [%s] processed in DB: %s\n",$params['file'],$po->id);
|
$po = ORM::factory('Photo',array('filename'=>$file));
|
||||||
|
|
||||||
|
if (! $po->loaded())
|
||||||
|
$po->filename = realpath($file);
|
||||||
|
|
||||||
|
$po->date_taken = $this->dbcol(strtotime($po->io('exif:DateTime')));
|
||||||
|
$po->signature = $this->dbcol($po->io()->getImageSignature());
|
||||||
|
$po->make = $this->dbcol($po->io('exif:Make'));
|
||||||
|
$po->model = $this->dbcol($po->io('exif:Model'));
|
||||||
|
$po->height = $this->dbcol($po->io()->getImageheight());
|
||||||
|
$po->width = $this->dbcol($po->io()->getImageWidth());
|
||||||
|
$po->orientation = $this->dbcol($po->io()->getImageOrientation());
|
||||||
|
$po->subsectime = $this->dbcol($po->io('exif:SubSecTimeOriginal'));
|
||||||
|
|
||||||
|
$po->gps_lat = $this->dbcol($po->gps(preg_split('/,\s?/',$po->io()->getImageProperty('exif:GPSLatitude')),$po->io()->getImageProperty('exif:GPSLatitudeRef')));
|
||||||
|
$po->gps_lon = $this->dbcol($po->gps(preg_split('/,\s?/',$po->io()->getImageProperty('exif:GPSLongitude')),$po->io()->getImageProperty('exif:GPSLongitudeRef')));
|
||||||
|
|
||||||
|
try {
|
||||||
|
$po->thumbnail = $this->dbcol(exif_thumbnail($po->filename));
|
||||||
|
} catch (Exception $e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ($params['verbose']) {
|
||||||
|
case 1:
|
||||||
|
print_r($po->what_changed());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
print_r($po->io()->getImageProperties());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$x = $po->list_duplicate()->find_all();
|
||||||
|
if (count($x)) {
|
||||||
|
$skip = FALSE;
|
||||||
|
|
||||||
|
foreach ($x as $o) {
|
||||||
|
# We'll only ignore based on the same signature.
|
||||||
|
if ($params['ignoredupe'] AND ($po->signature == $o->signature)) {
|
||||||
|
$skip = TRUE;
|
||||||
|
$this->writelog(sprintf("Ignore file [%s], it's the same as [%s (%s)]\n",$po->filename,$o->id,$o->file_path()));
|
||||||
|
break;
|
||||||
|
|
||||||
|
} elseif ($params['deletedupe'] AND ($po->signature == $o->signature) AND ($po->filename != $o->filename)) {
|
||||||
|
$skip = TRUE;
|
||||||
|
$this->writelog(sprintf("Delete file [%s], it's the same as [%s (%s)] with signature [%s]\n",$po->filename,$o->id,$o->file_path(),$po->signature));
|
||||||
|
unlink($file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unset($x);
|
||||||
|
|
||||||
|
if ($skip)
|
||||||
|
continue;
|
||||||
|
else
|
||||||
|
$po->duplicate = '1';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! $po->changed())
|
||||||
|
$this->writelog(sprintf("Image [%s] already in DB: %s\n",$file,$po->id));
|
||||||
|
|
||||||
|
$po->save();
|
||||||
|
|
||||||
|
if ($po->saved())
|
||||||
|
$this->writelog(sprintf("Image [%s] stored in DB: %s\n",$file,$po->id));
|
||||||
|
|
||||||
|
// Record our tags
|
||||||
|
foreach ($t as $o) {
|
||||||
|
$x = ORM::factory('Photo_Tag')->where('tag_id','=',$o->id)->where('photo_id','=',$po->id)->find();
|
||||||
|
$x->tag_id = $o->id;
|
||||||
|
$x->photo_id = $po->id;
|
||||||
|
$x->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Record our people
|
||||||
|
foreach ($p as $o) {
|
||||||
|
$x = ORM::factory('Photo_People',array('people_id'=>$o->id,'photo_id'=>$po->id));
|
||||||
|
$x->people_id = $o->id;
|
||||||
|
$x->photo_id = $po->id;
|
||||||
|
$x->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
unset($po);
|
||||||
|
unset($x);
|
||||||
|
unset($o);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($c > 1)
|
||||||
|
return sprintf("Images processed: %s\n",$c);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Force the return of a string or NULL
|
// Force the return of a string or NULL
|
||||||
private function dbcol($val,$noval=NULL) {
|
private function dbcol($val,$noval=NULL) {
|
||||||
return $val ? (string)$val : $noval;
|
return $val ? (string)$val : $noval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function writelog($msg) {
|
||||||
|
if (! $this->_log)
|
||||||
|
return;
|
||||||
|
|
||||||
|
static $fh = NULL;
|
||||||
|
|
||||||
|
if (is_null($fh))
|
||||||
|
$fh = fopen($this->_log,'a+');
|
||||||
|
|
||||||
|
fwrite($fh,$msg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
|
@ -13,6 +13,8 @@ class Task_Photo_Move extends Minion_Task {
|
|||||||
protected $_options = array(
|
protected $_options = array(
|
||||||
'file'=>NULL, // Photo File to Move
|
'file'=>NULL, // Photo File to Move
|
||||||
'batch'=>NULL, // Number of photos to move in a batch
|
'batch'=>NULL, // Number of photos to move in a batch
|
||||||
|
'useid'=>TRUE, // If date not in photo use ID
|
||||||
|
'verbose'=>FALSE, // Show some debuggig
|
||||||
);
|
);
|
||||||
|
|
||||||
protected function _execute(array $params) {
|
protected function _execute(array $params) {
|
||||||
@ -33,9 +35,12 @@ class Task_Photo_Move extends Minion_Task {
|
|||||||
|
|
||||||
$c = 0;
|
$c = 0;
|
||||||
foreach ($p->find_all() as $po) {
|
foreach ($p->find_all() as $po) {
|
||||||
if ($po->file_path() == $po->file_path(FALSE,TRUE))
|
if ($po->file_path() == $po->file_path(FALSE,($params['useid'] OR $po->date_taken) ? TRUE : FALSE))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if ($params['verbose'])
|
||||||
|
printf("Processing [%s], file [%s] - newpath [%s]\n",$po->id,$po->file_path(),$po->file_path(FALSE,($params['useid'] OR $po->date_taken) ? TRUE : FALSE));
|
||||||
|
|
||||||
if ($po->move())
|
if ($po->move())
|
||||||
printf("Photo [%s] moved to %s.\n",$po->id,$po->file_path());
|
printf("Photo [%s] moved to %s.\n",$po->id,$po->file_path());
|
||||||
else
|
else
|
||||||
|
32
application/classes/Task/Photo/Stat.php
Normal file
32
application/classes/Task/Photo/Stat.php
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<?php defined('SYSPATH') or die('No direct access allowed.');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find photos that dont match their database entries.
|
||||||
|
*
|
||||||
|
* @package Photo
|
||||||
|
* @category Tasks
|
||||||
|
* @author Deon George
|
||||||
|
* @copyright (c) 2014 Deon George
|
||||||
|
* @license http://dev.leenooks.net/license.html
|
||||||
|
*/
|
||||||
|
class Task_Photo_Stat extends Minion_Task {
|
||||||
|
protected $_options = array(
|
||||||
|
);
|
||||||
|
|
||||||
|
protected function _execute(array $params) {
|
||||||
|
$p = ORM::factory('Photo')->find_all();
|
||||||
|
|
||||||
|
foreach ($p as $po) {
|
||||||
|
if (! file_exists($po->file_path())) {
|
||||||
|
printf("ID [%s] doesnt exist (%s)?\n",$po->id,$po->file_path());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (($x=$po->io()->getImageSignature()) !== $po->signature) {
|
||||||
|
printf("ID [%s] signature doesnt match (%s) [%s != %s]?\n",$po->id,$po->file_path(),$po->signature,$x);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
Loading…
Reference in New Issue
Block a user