DataObjects/Images.php
[Pman.Core] / DataObjects / Images.php
1 <?php
2 /**
3  * Table Definition for Images
4  */
5 require_once 'DB/DataObject.php';
6
7 class Pman_Core_DataObjects_Images extends DB_DataObject 
8 {
9     ###START_AUTOCODE
10     /* the code below is auto generated do not remove the above tag */
11
12     public $__table = 'Images';                          // table name
13     public $id;                              // int(11)  not_null primary_key auto_increment
14     public $filename;                        // string(255)  not_null
15     public $ontable;                         // string(32)  not_null multiple_key
16     public $onid;                            // int(11)  not_null
17     public $mimetype;                        // string(64)  not_null
18     public $width;                           // int(11)  not_null
19     public $height;                          // int(11)  not_null
20     public $filesize;                        // int(11)  not_null
21     public $displayorder;                    // int(11)  not_null
22     public $language;                        // string(6)  not_null
23     public $parent_image_id;                 // int(11)  not_null
24     public $created;                         // datetime(19)  not_null binary
25     public $imgtype;                         // string(32)  not_null
26     public $linkurl;                         // string(254)  not_null
27     public $descript;                        // blob(65535)  not_null blob
28     public $title;                           // string(128)  not_null
29     
30     /* the code above is auto generated do not remove the tag below */
31     ###END_AUTOCODE
32     
33     function checkPerm($perm, $au)
34     {
35         // default permissons are to
36         // allow create / edit / if the user has
37         
38         if (!$au) {
39             
40           
41             
42             return false;
43         }
44         
45         $o = $this->object();
46         //print_r($o);
47         if (method_exists($o, 'hasPerm')) {
48             // edit permissions on related object needed...
49             return $o->hasPerm( $perm == 'S' ? 'S' : 'E' , $au);
50             
51         }
52         
53         return true; //// ??? not really that safe...
54         
55     }
56     
57     function beforeInsert($q, $roo) 
58     {
59         if (isset($q['_remote_upload'])) {
60             require_once 'System.php';
61             
62             $tmpdir  = System::mktemp("-d remote_upload");
63             
64             $path = $tmpdir . '/' . basename($q['_remote_upload']);
65             
66             if(!file_exists($path)){
67                file_put_contents($path, file_get_contents($q['_remote_upload'])); 
68             }
69             
70             $imageInfo = getimagesize($path);
71             
72             require_once 'File/MimeType.php';
73             $y = new File_MimeType();
74             $ext = $y->toExt(trim((string) $imageInfo['mime'] ));
75             
76             if (!preg_match("/\." . $ext."$/", $path, $matches)) {
77                 rename($path,$path.".".$ext);
78                 $path.= ".".$ext;
79             }
80             
81             if (!$this->createFrom($path)) {
82                 $roo->jerr("erro making image" . $q['_remote_upload']);
83             }
84             
85             if(!empty($q['_return_after_create'])){
86                 return;
87             }
88             
89             $roo->addEvent("ADD", $this, $this->toEventString());
90         
91             $r = DB_DataObject::factory($this->tableName());
92             $r->id = $this->id;
93             $roo->loadMap($r);
94             $r->limit(1);
95             $r->find(true);
96             $roo->jok($r->URL(-1,'/Images') . '#attachment-'.  $r->id);
97         }
98         
99         if(isset($q['_auto_save'])){
100             require_once 'System.php';
101             
102             $tmpdir  = System::mktemp("-d auto_save");
103             
104             $path = $tmpdir . '/' . time() . '.json';
105             
106             if(!file_exists($path)){
107                file_put_contents($path, $q['_source']); 
108             }
109             
110              $imageInfo = getimagesize($path);
111             
112             require_once 'File/MimeType.php';
113             $y = new File_MimeType();
114             $ext = $y->toExt(trim((string) $imageInfo['mime'] ));
115             
116             if (!preg_match("/\." . $ext."$/", $path, $matches)) {
117                 rename($path,$path.".".$ext);
118                 $path.= ".".$ext;
119             }
120             
121             if (!$this->createFrom($path)) {
122                 $roo->jerr("error on auto save making image");
123             }
124             
125             $roo->addEvent("AUTOSAVE", $this, $this->toEventString());
126         }
127         
128     }
129     
130      
131     /**
132      * create an email from file.
133      * these must have been set first.
134      * ontable / onid.
135      * 
136      */
137     function createFrom($file, $filename=false)
138     {
139         // copy the file into the storage area..
140         if (!file_exists($file) || !filesize($file)) {
141             return false;
142         }
143         
144         $filename = empty($filename) ? $file : $filename;
145         
146         if (empty($this->mimetype)) {
147             require_once 'File/MimeType.php';
148             $y = new File_MimeType();
149             $this->mimetype = $y->fromFilename($filename);
150         }
151         
152         $this->mimetype= strtolower($this->mimetype);
153         
154         if (array_shift(explode('/', $this->mimetype)) == 'image') { 
155         
156             $imgs = @getimagesize($file);
157             
158             if (empty($imgs) || empty($imgs[0]) || empty($imgs[1])) {
159                 // it's a file!!!!
160             } else {
161                 list($this->width , $this->height)  = $imgs;
162             }
163         }
164         
165         $this->filesize = filesize($file);
166         $this->created = date('Y-m-d H:i:s');
167          
168         
169         if (empty($this->filename)) {
170             $this->filename = basename($filename);
171         }
172         
173         //DB_DataObject::debugLevel(1);
174         if (!$this->id) {
175             $this->insert();
176         } else {
177             $this->update();
178         }
179         
180         
181         
182         $f = $this->getStoreName();
183         $dest = dirname($f);
184         if (!file_exists($dest)) {
185             // currently this is 0775 due to problems using shared hosing (FTP)
186             // it makes all the files unaccessable..
187             // you can normally solve this by giving the storedirectory better perms
188             // if needed on a dedicated server..
189             $oldumask = umask(0);
190             mkdir($dest, 0775, true);
191             umask($oldumask);  
192         }
193         
194         copy($file,$f);
195         
196         // fill in details..
197         
198         /* thumbnails */
199         
200      
201        // $this->createThumbnail(0,50);
202         return true;
203         
204     }
205
206     /**
207      * Calculate target file name
208      *
209      * @return - target file name
210      */
211     function getStoreName() 
212     {
213         $opts = HTML_FlexyFramework::get()->Pman;
214         $fn = preg_replace('/[^a-z0-9\.]+/i', '_', $this->filename);
215         return implode( '/', array(
216             $opts['storedir'], '_images_', date('Y/m', strtotime($this->created)), $this->id . '-'. $fn
217         ));
218           
219     }
220      
221     /**
222      * deletes all the image instances of it...
223      * 
224      * 
225      */
226     function beforeDelete()
227     {
228         $fn = $this->getStoreName();
229         if (file_exists($fn)) {
230             unlink($fn);
231         }
232         // delete thumbs..
233         $b = basename($fn);
234         $d = dirname($fn);
235         if (file_exists($d)) {
236                 
237             $dh = opendir($d);
238             while (false !== ($fn = readdir($dh))) {
239                 if (substr($fn, 0, strlen($b)) == $b) {
240                     unlink($d. '/'. $fn);
241                 }
242             }
243         }
244         
245     }
246     /**
247      * check mimetype against type
248      * - eg. img.is(#image#)
249      *
250      */
251     function is($type)
252     {
253         if (empty($this->mimetype)) {
254             return false;
255         }
256         return 0 === strcasecmp($type, array_shift(explode('/',$this->mimetype)));
257     }
258   
259     /**
260      * onUpload (singlely attached image to a table)
261      */
262     
263     function onUploadWithTbl($tbl,  $fld)
264     {
265         if ( $tbl->__table == 'Images') {
266             return; // not upload to self...
267         }
268         if (empty($_FILES['imageUpload']['tmp_name']) || 
269             empty($_FILES['imageUpload']['name']) || 
270             empty($_FILES['imageUpload']['type'])
271         ) {
272             return false;
273         }
274         if ($tbl->$fld) {
275             $image = DB_DataObject::factory('Images');
276             $image->get($tbl->$fld);
277             $image->beforeDelete();
278             $image->delete();
279         }
280         
281         $image = DB_DataObject::factory('Images');
282         $image->onid = $tbl->id;
283         $image->ontable = $tbl->__table;
284         $image->filename = $_FILES['imageUpload']['name']; 
285         $image->mimetype = $_FILES['imageUpload']['type'];
286        
287         if (!$image->createFrom($_FILES['imageUpload']['tmp_name'])) {
288             return false;
289         }
290         $old = clone($tbl);
291         $tbl->$fld = $image->id;
292         $tbl->update($old);
293          
294     }
295     
296     // direct via roo...
297     /// ctrl not used??
298     function onUpload($roo)
299     {
300 //        echo $_FILES['imageUpload']['type'];exit;
301         if (empty($_FILES['imageUpload']['tmp_name']) || 
302             empty($_FILES['imageUpload']['name']) || 
303             empty($_FILES['imageUpload']['type'])
304         ) {
305             $this->err = "Missing file details";
306             return false;
307         }
308         
309         if ($this->id) {
310             $this->beforeDelete();
311         }
312         if ( empty($this->ontable)) {
313             $this->err = "Missing  ontable";
314             return false;
315         }
316         
317         if (!empty($this->imgtype) && $this->imgtype[0] == '-' && !empty($this->onid)) {
318             // then its an upload 
319             $img  = DB_DataObject::factory('Images');
320             $img->onid = $this->onid;
321             $img->ontable = $this->ontable;
322             $img->imgtype = $this->imgtype;
323             
324             $img->find();
325             while ($img->fetch()) {
326                 $img->beforeDelete();
327                 $img->delete();
328             }
329             
330         }
331         
332         
333         
334         require_once 'File/MimeType.php';
335         $y = new File_MimeType();
336         $this->mimetype = $_FILES['imageUpload']['type'];
337         if (in_array($this->mimetype, array(
338                         'text/application',
339                         'application/octet-stream',
340                         'image/x-png',  // WTF does this?
341                         'image/pjpeg',  // WTF does this?
342                         'application/x-apple-msg-attachment', /// apple doing it's magic...
343                         'application/vnd.ms-excel',   /// sometimes windows reports csv as excel???
344                         'application/csv-tab-delimited-table', // windows again!!?
345                 ))) { // weird tyeps..
346             $inf = pathinfo($_FILES['imageUpload']['name']);
347             $this->mimetype  = $y->fromExt($inf['extension']);
348         }
349         
350         
351         $ext = $y->toExt(trim((string) $this->mimetype ));
352         
353         $this->filename = empty($this->filename) ? 
354             $_FILES['imageUpload']['name'] : ($this->filename .'.'. $ext); 
355         
356         
357         
358         if (!$this->createFrom($_FILES['imageUpload']['tmp_name'])) {
359             return false;
360         }
361         return true;
362          
363     }
364      
365     
366     
367     /**
368      * return a list of images for an object, optionally with a mime regex.
369      * eg. '%/pdf' or 'image/%'
370      *
371      * usage:
372      *
373      * $i = DB_DataObject::factory('Images');
374      * $i->imgtype = 'LOGO';
375      * $ar = $i->gather($somedataobject, 'image/%');
376      * 
377      * @param {DB_DataObject} dataobject  = the object to gather data on.
378      * @param {String} mimelike  LIKE query to use for search
379      
380      */
381     function gather($obj, $mime_like='', $opts=array())
382     {
383         //DB_DataObject::debugLevel(1);
384         if (empty($obj->id)) {
385             return array();
386         }
387         
388         $c = clone($this);
389         $c->whereAddIn($this->tableName() . '.ontable', array( $obj->tableName(), $obj->__table) , 'string');
390         $c->onid = $obj->id;
391         $c->autoJoin();
392         if (!empty($mime_like)) {
393             $c->whereAdd("Images.mimetype LIKE '". $c->escape($mime_like) ."'");
394         }
395
396         return $c->fetchAll();
397     }
398      
399     
400     /**
401     * set or get the dataobject this image is associated with
402     * @param DB_DataObject $obj An object to associate this image with
403     *        (does not store it - you need to call update() to do that)
404     * @return DB_DataObject the dataobject this image is attached to.
405     */
406     function object($obj=false)
407     {
408         if ($obj === false) {
409             if (empty($this->ontable) || empty($this->onid)) {
410                 return false;
411             }
412             $ret = DB_DataObject::factory($this->ontable);
413             $ret->get($this->onid);
414             return $ret;
415         }
416         
417         
418         $this->ontable = $obj->tableName();
419         $this->onid = $obj->id; /// assumes our nice standard of using ids..
420         return $obj;
421     }
422     
423      
424     function toRooArray($req = array()) {
425       //  echo '<PRE>';print_r($req);exit;
426         $ret= $this->toArray();
427       
428         static $ff = false;
429         if (!$ff) {
430             $ff = HTML_FlexyFramework::get();
431         }
432         
433         $ret['public_baseURL'] = isset($ff->Pman_Images['public_baseURL']) ?
434                     $ff->Pman_Images['public_baseURL'] : $ff->baseURL;
435         
436         if (!empty($req['query']['imagesize'])) {
437              $baseURL = isset($req['query']['imageBaseURL']) ? $req['query']['imageBaseURL'] : false;
438             
439             $ret['url'] = $this->URL(-1, '/Images/Download',$baseURL);
440             
441             $ret['url_view'] = $this->URL(-1, '/Images',$baseURL);    
442             
443             if (!empty($req['query']['imagesize'])) {
444                 $ret['url_thumb'] = $this->URL($req['query']['imagesize'], '/Images/Thumb',$baseURL);
445             }
446         }
447         
448          
449          
450         return $ret;
451     }
452     
453     /**
454      * URL - create  a url for the image.
455      * size - use -1 to show full size.
456      * provier = baseURL + /Images/Thumb ... use '/Images/' for full
457      * 
458      * 
459      */
460     function URL($size , $provider = '/Images/Thumb', $baseURL=false)
461     {
462         if (!$this->id) {
463             return 'about:blank';
464             
465         }
466
467         $ff = HTML_FlexyFramework::get();
468         $baseURL = $baseURL ? $baseURL : $ff->baseURL ;
469         if (preg_match('#^http[s]*://#', $provider)) {
470             $baseURL = '';
471         }
472        
473         if ($size < 0) {
474             $provider = preg_replace('#/Thumb$#', '', $provider);
475             
476             return $baseURL . $provider . "/{$this->id}/{$this->filename}";
477         }
478         //-- max?
479         //$size = max(100, (int) $size);
480         //$size = min(1024, (int) $size);
481         // the size should 200x150 to convert
482         $sizear = preg_split('/(x|c)/', $size);
483         if(empty($sizear[1])){
484             $sizear[1] = 0;
485         }
486         $size = implode(strpos($size,'c') > -1 ? 'c' : 'x', $sizear);
487 //        print_r($size);
488         $fc = $this->toFileConvert();
489 //        print_r($size);
490 //        exit;
491         $fc->convert($this->mimetype, $size);
492         
493         
494         return $baseURL . $provider . "/$size/{$this->id}/{$this->filename}";
495     }
496     /**
497      * size could be 123x345
498      * 
499      * 
500      */
501     function toHTML($size, $provider = '/Images/Thumb') 
502     {
503         
504         
505         
506         $sz = explode('x', $size);
507         $sx = $sz[0];
508         //var_dump($sz);
509         if (!$this->id || empty($this->width)) {
510             $this->height = $sx;
511             $this->width = empty($sz[1]) ? $sx : $sz[1];
512             $sy = $this->width ;
513         }
514         if (empty($sz[1])) {
515             $ratio =  empty($this->width) ? 1 : $this->height/ ($this->width *1.0);
516             $sy = $ratio * $sx;
517         } else {
518             $sy = $sz[1];
519         }
520         // create it?
521         $extra = '';
522         if (strlen($this->title)) {
523             $extra = ' title="'. htmlspecialchars($this->title) . '"';
524         }
525         
526         return '<img src="' . $this->URL($size, $provider) . '"' .
527                 $extra .
528                 ' width="'. $sx . '"' .
529                 ' height="'. $sy . '">';
530         
531         
532     }
533     
534     /**
535      * 
536      * #2142 [new] CMS - image link urls
537      * 
538      * 
539      * 
540      */
541     function toLinkHTML($size, $provider = '/Images/Thumb')
542     {
543         if(empty($this->linkurl)){
544             return $this->toHTML($size, $provider = '/Images/Thumb');
545         }
546         
547         return '<a href="'.$this->linkurl.'" target="_blank">'.$this->toHTML($size, $provider = '/Images/Thumb').'</a>';
548         
549     }
550     
551     
552     /**
553      * to Fileconvert object..
554      *
555      *
556      *
557      */
558     function toFileConvert()
559     {
560         require_once 'File/Convert.php';
561         $fc = new File_Convert($this->getStoreName(), $this->mimetype);
562         return $fc;
563         
564     }
565     
566     function fileExt()
567     {
568         require_once 'File/MimeType.php';
569         
570         $y = new File_MimeType();
571         return  $y->toExt($this->mimetype);
572         
573         
574     }
575     
576     /**
577      *
578      *
579      *
580      */
581     
582     
583     function setFromRoo($ar, $roo)
584     {
585         // not sure why we do this.. 
586         
587         // if imgtype starts with '-' ? then we set the 'old' (probably to delete later)
588         if (!empty($ar['imgtype']) && !empty($ar['ontable']) && !empty($ar['onid']) && ($ar['imgtype'][0] == '-')) {
589             $this->setFrom($ar);
590             $this->limit(1);
591             if ($this->find(true)) {
592                 $roo->old = clone($this);
593             }
594         }   
595             
596         
597         if (!empty($ar['_copy_from'])) {
598             
599             if (!$this->checkPerm( 'A' , $roo->authUser))  {
600                 $roo->jerr("IMAGE UPLOAD PERMISSION DENIED");
601             }
602             
603             $copy = DB_DataObject::factory('Images');
604             $copy->get($ar['_copy_from']);
605             $this->setFrom($copy->toArray());
606             $this->setFrom($ar);
607             $this->createFrom($copy->getStoreName());
608             
609             $roo->addEvent("ADD", $this, $this->toEventString());
610             
611             $r = DB_DataObject::factory($this->tableName());
612             $r->id = $this->id;
613             $roo->loadMap($r);
614             $r->limit(1);
615             $r->find(true);
616             $roo->jok($r->toArray());
617             
618             
619         }
620         
621          
622         
623         // FIXME - we should be checking perms here...
624        
625         // this should be doign update
626         $this->setFrom($ar);
627          
628         if (!$this->checkPerm($this->id ? 'A' : 'E', $roo->authUser))  {
629             $roo->jerr("IMAGE UPLOAD PERMISSION DENIED");
630         }
631         
632         
633         
634         if (!isset($_FILES['imageUpload'])) {
635             return; // standard update...
636         }
637         
638         
639 //        print_r(!$this->onUpload($this));
640         
641         if ( !$this->onUpload($this)) { 
642             $roo->jerr("File upload failed : ". (!empty($this->err) ? $this->err : ''));
643         }
644         
645         $roo->addEvent("ADD", $this, $this->toEventString());
646         
647         $r = DB_DataObject::factory($this->tableName());
648         $r->id = $this->id;
649         $roo->loadMap($r);
650         $r->limit(1);
651         $r->find(true);
652         $roo->jok($r->toArray());
653          
654     }
655     
656     function toEventString()
657     {
658         
659         //$p = DB_DataObject::factory($this->ontable);
660         //if (!is_$p) {
661         //    return "ERROR unknown table? {$this->ontable}";
662        // }
663         //$p->get($p->onid);
664         
665         return $this->filename .' - on ' . $this->ontable . ':' . $this->onid;
666         //$p->toEventString();
667     }
668     
669  }