root/trunk/wifidog-auth/wifidog/classes/Content/File/File.php @ 1090

Revision 1090, 21.2 KB (checked in by benoitg, 7 years ago)

filter content type according to various criteria. Will be used more
extensively in the profile manager.

  • Content manager: Use content type filter to only allow Simple

content types (Content without metadata) to be used for metadata.

banner adds, or any other image rotation. Size constraints not yet
implemented

  • Move externally maintained class.phpmailer.php, class.smtp.php

into lib where they belong

  • DateTime?.php: Make class handle an empty date sensibly.
  • Network.php: Show the network again when there is only one.

It was confusing in some screens.

  • page.php: Clarify error message, and set a more reasonnable

paging cascade:

5 min, 30 min, 2 hours, 1 day, 1 week, 1 month

  • Finally fix #127
  • At last, working content scheduled display and expiration for

ContentGroups?. Archiving does not yet have a UI. Content that expires
will simply seem to disapear.

  • Fix #247 (somebody filed a bug before I commited, conveniently

saving me the need to describe it).

  • The Fix for #106 in [1089] returned non-objects, causing error

messages and not displaying what it was meant to display.

Used Guest instead of Annonymous, which will probably be

used for different purpose in the future.

This re-fix does not include duplicate counting yet.

Splash users are not the only users that could log-in multiple times.

I don't have a staging server here, a fix will be

commited in a few minutes if something goes wrong.

  • Cleanup coments.
  • Sync schemas
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1<?php
2
3/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
4
5// +-------------------------------------------------------------------+
6// | WiFiDog Authentication Server                                     |
7// | =============================                                     |
8// |                                                                   |
9// | The WiFiDog Authentication Server is part of the WiFiDog captive  |
10// | portal suite.                                                     |
11// +-------------------------------------------------------------------+
12// | PHP version 5 required.                                           |
13// +-------------------------------------------------------------------+
14// | Homepage:     http://www.wifidog.org/                             |
15// | Source Forge: http://sourceforge.net/projects/wifidog/            |
16// +-------------------------------------------------------------------+
17// | This program is free software; you can redistribute it and/or     |
18// | modify it under the terms of the GNU General Public License as    |
19// | published by the Free Software Foundation; either version 2 of    |
20// | the License, or (at your option) any later version.               |
21// |                                                                   |
22// | This program is distributed in the hope that it will be useful,   |
23// | but WITHOUT ANY WARRANTY; without even the implied warranty of    |
24// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     |
25// | GNU General Public License for more details.                      |
26// |                                                                   |
27// | You should have received a copy of the GNU General Public License |
28// | along with this program; if not, contact:                         |
29// |                                                                   |
30// | Free Software Foundation           Voice:  +1-617-542-5942        |
31// | 59 Temple Place - Suite 330        Fax:    +1-617-542-2652        |
32// | Boston, MA  02111-1307,  USA       gnu@gnu.org                    |
33// |                                                                   |
34// +-------------------------------------------------------------------+
35
36/**
37 * @package    WiFiDogAuthServer
38 * @subpackage ContentClasses
39 * @author     Francois Proulx <francois.proulx@gmail.com>
40 * @author     Max Horvath <max.horvath@maxspot.de>
41 * @copyright  2005-2006 Francois Proulx, Technologies Coeus inc.
42 * @copyright  2005-2006 Max Horvath, maxspot GmbH
43 * @version    Subversion $Id$
44 * @link       http://www.wifidog.org/
45 */
46
47/**
48 * Binary or ASCII file
49 *
50 * @package    WiFiDogAuthServer
51 * @subpackage ContentClasses
52 * @author     Francois Proulx <francois.proulx@gmail.com>
53 * @author     Max Horvath <max.horvath@maxspot.de>
54 * @copyright  2005-2006 Francois Proulx, Technologies Coeus inc.
55 * @copyright  2005-2006 Max Horvath, maxspot GmbH
56 */
57class File extends Content
58{
59
60    /**
61     * File size unit: Byte
62
63     */
64    const UNIT_BYTES = 1;
65
66    /**
67     * File size unit: KB
68
69     */
70    const UNIT_KILOBYTES = 1024;
71
72    /**
73     * File size unit: MB
74
75     */
76    const UNIT_MEGABYTES = 1048576;
77
78    /**
79     * File size unit: GB
80
81     */
82    const UNIT_GIGABYTES = 1073741824;
83
84    /**
85     * Constructor
86     *
87     * @param string $content_id Content id
88     */
89    public function __construct($content_id)
90    {
91        // Define globals
92        global $db;
93
94        // Init values
95        $row = null;
96
97        parent :: __construct($content_id);
98
99        $content_id = $db->escapeString($content_id);
100        $sql = "SELECT * FROM content_file WHERE files_id='$content_id'";
101        $db->execSqlUniqueRes($sql, $row, false);
102
103        if ($row == null) {
104            /*
105             * Since the parent Content exists, the necessary data in
106             * content_group had not yet been created
107             */
108            $sql = "INSERT INTO content_file (files_id) VALUES ('$content_id')";
109            $db->execSqlUpdate($sql, false);
110
111            $sql = "SELECT * FROM content_file WHERE files_id='$content_id'";
112            $db->execSqlUniqueRes($sql, $row, false);
113
114            if ($row == null) {
115                throw new Exception(_("The content with the following id could not be found in the database: ").$content_id);
116            }
117        }
118
119        $this->mBd = &$db;
120        $this->files_row = $row;
121    }
122
123    /**
124     * Set Binary data from a POST form data field
125     *
126     * @param string $upload_field The form field that contains the data
127     *
128     * @return bool True if successful
129
130     */
131    private function setBinaryDataFromPostVar($upload_field)
132    {
133        // Init values
134        $_retval = false;
135
136        if (!empty ($_FILES[$upload_field]) && $_FILES[$upload_field]['error'] == UPLOAD_ERR_OK) {
137            // Unlink BLOB if any exists
138            $blob_oid = $this->getBinaryDataOid();
139
140            if ($blob_oid) {
141                $this->mBd->unlinkLargeObject($blob_oid);
142            }
143
144            // Updating database
145            // Create a new BLOB
146            $new_oid = $this->mBd->importLargeObject($_FILES[$upload_field]['tmp_name']);
147            // Switch to new OID and touch file
148            $this->setBinaryDataOid($new_oid);
149            $this->setLocalFileSize($_FILES[$upload_field]['size']);
150            $this->setMimeType($_FILES[$upload_field]['type']);
151            $this->setFilename($_FILES[$upload_field]['name']);
152
153            $_retval = true;
154        } else {
155            switch ($_FILES[$upload_field]['error'])
156            {
157            case 'UPLOAD_ERR_INI_SIZE':
158                echo _("File size exceeds limit specified in PHP.ini");
159                break;
160
161            case 'UPLOAD_ERR_FORM_SIZE':
162                echo _("File size exceeds limit specified HTML form");
163                break;
164
165            case 'UPLOAD_ERR_PARTIAL':
166                echo _("File upload was interrupted");
167                break;
168
169            case 'UPLOAD_ERR_NO_TMP_DIR':
170                echo _("Missing temp folder");
171                break;
172
173            }
174        }
175
176        return $_retval;
177    }
178
179    /**
180     * Returns the binary data from the database
181     *
182     * @return string Binary data from the database
183
184     */
185    private function getBinaryDataOid()
186    {
187        return $this->mBd->unescapeBinaryString($this->files_row['data_blob']);
188    }
189
190    /**
191     * Saves the binary data to the database
192     *
193     * @param string $oid Binary data
194     *
195     * @return void
196
197     */
198    private function setBinaryDataOid($oid)
199    {
200        if (is_null($oid)) {
201            $oid = "NULL";
202        }
203
204        $this->mBd->execSqlUpdate("UPDATE content_file SET data_blob = $oid WHERE files_id='".$this->getId()."'", false);
205        // Touch and refresh this object
206        $this->touch();
207    }
208
209        /**
210         * Return creation date (read-only)
211         *
212         * @return string ISO-8601-2000 timestamp
213         */
214    public function getCreationDate()
215    {
216                return $this->files_row['creation_date'];
217    }
218
219        /**
220         * Return update date
221         *
222         * @return string ISO-8601-2000 timestamp
223         */
224    public function getLastUpdateDate()
225    {
226                return $this->files_row['last_update_date'];
227    }
228
229    /**
230         * Touch file, update timestamp
231         *
232         */
233    public function touch()
234    {
235                $this->mBd->execSqlUpdate("UPDATE content_file SET last_update_date = NOW() WHERE files_id='".$this->getId()."'", false);
236        $this->refresh();
237    }
238
239    /**
240     * Returns the MIME type of the file
241     *
242     * @return string MIME type of file
243     */
244    public function getMimeType()
245    {
246        return $this->files_row['mime_type'];
247    }
248
249    /**
250     * Saves the MIME type of the file
251     *
252     * @param string $mime_type
253     *
254     * @return void
255     */
256    private function setMimeType($mime_type)
257    {
258        $mime_type = $this->mBd->escapeString($mime_type);
259        $this->mBd->execSqlUpdate("UPDATE content_file SET mime_type ='".$mime_type."' WHERE files_id='".$this->getId()."'", false);
260        // Touch and refresh this object
261        $this->touch();
262    }
263
264    /**
265     * Returns the filename of the file
266     *
267     * @return string Filename of file
268
269     */
270    protected function getFilename()
271    {
272        return $this->files_row['filename'];
273    }
274
275    /**
276     * Stores the filename of the file
277     *
278     * @param string $file_name Filename of the file
279     *
280     * @return void
281     */
282    private function setFilename($file_name)
283    {
284        $file_name = $this->mBd->escapeString($file_name);
285        $this->mBd->execSqlUpdate("UPDATE content_file SET filename ='".$file_name."' WHERE files_id='".$this->getId()."'", false);
286        // Touch and refresh this object
287        $this->touch();
288    }
289
290    /**
291     * Returns the size of the file
292     *
293     * @param string $unit Name of constant of which kind of filesize unit
294     *                     to use
295     *                     Possibilities:
296     *                       + self::UNIT_BYTES
297     *                       + self::UNIT_KILOBYTES
298     *                       + self::MEGABYTES
299     *                       + self::GIGABYTES
300     *
301     * @return float Size of file
302     */
303    protected function getFileSize($unit = self::UNIT_BYTES)
304    {
305        if ($this->isLocalFile()) {
306            $size = $this->files_row['local_binary_size'];
307        } else {
308            $size = $this->files_row['remote_size'];
309        }
310
311        switch ($unit) {
312        case self::UNIT_KILOBYTES:
313        case self::UNIT_MEGABYTES:
314        case self::UNIT_GIGABYTES:
315        case self::UNIT_BYTES:
316            $size = round($size / $unit, 2);
317            break;
318
319        }
320
321        return $size;
322    }
323
324    /**
325     * Sets the size of a local file
326     *
327     * @param int    $size Size of file
328     * @param string $unit Name of constant of which kind of filesize unit
329     *                     to use
330     *                     Possibilities:
331     *                       + self::UNIT_BYTES
332     *                       + self::UNIT_KILOBYTES
333     *                       + self::MEGABYTES
334     *                       + self::GIGABYTES
335     *
336     * @return void
337     */
338    private function setLocalFileSize($size, $unit = self::UNIT_BYTES)
339    {
340        if (is_numeric($size)) {
341            $octet_size = $size * $unit;
342
343            $this->mBd->execSqlUpdate("UPDATE content_file SET local_binary_size = $octet_size WHERE files_id='" . $this->getId() . "'", false);
344            $this->refresh();
345        }
346    }
347
348    /**
349     * Sets the size of a remote file
350     *
351     * @param int    $size Size of file
352     * @param string $unit Name of constant of which kind of filesize unit
353     *                     to use
354     *                     Possibilities:
355     *                       + self::UNIT_BYTES
356     *                       + self::UNIT_KILOBYTES
357     *                       + self::MEGABYTES
358     *                       + self::GIGABYTES
359     *
360     * @return void
361
362     */
363    private function setRemoteFileSize($size, $unit = self::UNIT_KILOBYTES)
364    {
365        if (is_numeric($size)) {
366            $octet_size = $size * $unit;
367
368            $this->mBd->execSqlUpdate("UPDATE content_file SET remote_size = $octet_size WHERE files_id='".$this->getId()."'", false);
369            $this->refresh();
370        }
371    }
372
373    /**
374     * Get URL of file
375     *
376     * @return string URL of file
377     */
378    public function getFileUrl()
379    {
380        // Init values
381        $_retval = null;
382
383        if (!$this->isLocalFile()) {
384            $_retval = $this->files_row['url'];
385        } else {
386            $_retval = BASE_SSL_PATH . "file_download.php?file_id=" . $this->getId();
387        }
388
389        return $_retval;
390    }
391
392    /**
393     * Sets URL of a file
394     *
395     * @param string $url
396     *
397     * @return void
398
399     */
400    private function setURL($url)
401    {
402        if ($url == null) {
403            $url = "NULL";
404        } else {
405            $url = "'".$this->mBd->escapeString($url)."'";
406        }
407
408        $this->mBd->execSqlUpdate("UPDATE content_file SET url = $url WHERE files_id='".$this->getId()."'", false);
409        $this->refresh();
410    }
411
412    /**
413     * Returns if file is a local file
414     *
415     * @return bool True if file is local
416     */
417    protected function isLocalFile()
418    {
419        return is_null($this->files_row['url']);
420    }
421
422    /**
423     * Shows the administration interface for RssAggregator.
424     *
425     * @param string $subclass_admin_interface HTML code to be added after the
426     *                                         administration interface
427     *
428     * @return string HTML code for the administration interface
429     */
430    public function getAdminUI($subclass_admin_interface = null, $title=null)
431    {
432        // Init values
433        $html = '';
434
435        $html .= "<div class='admin_element_item_container'>\n";
436        $html .= "<div class='admin_element_label'>"._("Creation date")." : </div>\n";
437        $html .= "<div class='admin_element_data'>\n";
438        $html .= $this->getCreationDate();
439        $html .= "</div>\n";
440        $html .= "</li>\n";
441
442        $html .= "<div class='admin_element_item_container'>\n";
443        $html .= "<div class='admin_element_label'>"._("Last update date")." : </div>\n";
444        $html .= "<div class='admin_element_data'>\n";
445        $html .= $this->getLastUpdateDate();
446        $html .= "</div>\n";
447        $html .= "</li>\n";
448
449        $html .= "<li class='admin_element_item_container'>\n";
450        $html .= "<div class='admin_element_label'>";
451        $html .= "<input type='radio' name='file_mode".$this->getId()."' value='by_upload' ". ($this->isLocalFile() ? "CHECKED" : "").">";
452        $html .= _("Upload a new file (Uploading a new one will replace any existing file)")." : </div>\n";
453        $html .= "<div class='admin_element_data'>\n";
454        $html .= '<input type="hidden" name="MAX_FILE_SIZE" value="1073741824" />';
455        $html .= '<input name="file_file_upload'.$this->getId().'" type="file" />';
456        $html .= "</div>\n";
457        $html .= "</li>\n";
458
459        $html .= "<li class='admin_element_item_container'>\n";
460        $html .= "<div class='admin_element_label'>";
461        $html .= "<input type='radio' name='file_mode".$this->getId()."' value='remote' ". (!$this->isLocalFile() ? "CHECKED" : "").">";
462        $html .= _("Remote file via URL")." : </div>\n";
463        $html .= "<div class='admin_element_data'>\n";
464
465        if ($this->isLocalFile()) {
466            $html .= "<input name='file_url".$this->getId()."' type='text' size='50'/>";
467        } else {
468            $html .= "<input name='file_url".$this->getId()."' type='text' size='50' value='".$this->getFileUrl()."'/>";
469        }
470
471        $html .= "</div>\n";
472        $html .= "</li>\n";
473
474        if (!$this->isLocalFile()) {
475            $html .= "<div class='admin_element_item_container'>\n";
476            $html .= "<div class='admin_element_label'>"._("File URL")." : </div>\n";
477            $html .= "<div class='admin_element_data'>\n";
478            $html .= $this->getFileUrl();
479            $html .= "</div>\n";
480            $html .= "</li>\n";
481        }
482
483        $html .= "<li class='admin_element_item_container'>\n";
484        $html .= "<div class='admin_element_label'>"._("Filename to display")." : </div>\n";
485        $html .= "<div class='admin_element_data'>\n";
486        $html .= '<input type="text" name="file_file_name'.$this->getId().'" value="'.$this->getFilename().'" />';
487        $html .= "</div>\n";
488        $html .= "</li>\n";
489
490        if ($this->isLocalFile()) {
491            $html .= "<li class='admin_element_item_container'>\n";
492            $html .= "<div class='admin_element_label'>"._("MIME type")." : </div>\n";
493            $html .= "<div class='admin_element_data'>\n";
494            $html .= '<input type="text" name="file_mime_type'.$this->getId().'" value="'.$this->getMimeType().'" />';
495            $html .= "</div>\n";
496            $html .= "</li>\n";
497
498            $html .= "<li class='admin_element_item_container'>\n";
499            $html .= "<div class='admin_element_label'>"._("Locally stored file size")." : </div>\n";
500            $html .= "<div class='admin_element_data'>\n";
501            $html .= $this->getFileSize(self :: UNIT_KILOBYTES)." "._("KB");
502            $html .= "</div>\n";
503            $html .= "</li>\n";
504        } else {
505            $html .= "<div class='admin_element_item_container'>\n";
506            $html .= "<div class='admin_element_label'>"._("Remote file size (Automatically converted from KB to Bytes)")." : </div>\n";
507            $html .= "<div class='admin_element_data'>\n";
508            // The hidden field contains old value to determine if we have to update ( this prevents unwanted successive floating point evaluation )
509            $html .= '<input type="hidden" name="file_old_remote_size'.$this->getId().'" value="'.$this->getFileSize().'" />';
510            $html .= '<input type="text" name="file_remote_size'.$this->getId().'" value="'.$this->getFileSize().'" />';
511            $html .= "</div>\n";
512            $html .= "</li>\n";
513        }
514
515        $html .= "<li class='admin_element_item_container'>\n";
516        $html .= "<div class='admin_element_data'>\n";
517        $html .= "<a href='".$this->getFileUrl()."'>"._("Download")." ".$this->getFilename()." (".$this->getFileSize(self :: UNIT_KILOBYTES)." "._("KB").")</a>";
518        $html .= "</div>\n";
519        $html .= "</li>\n";
520
521        $html .= $subclass_admin_interface;
522
523        return parent::getAdminUI($html, $title);
524    }
525
526    /**
527     * Processes the input of the administration interface for RssAggregator
528     *
529     * @return void
530     */
531    public function processAdminUI()
532    {
533        if ($this->isOwner(User :: getCurrentUser()) || User :: getCurrentUser()->isSuperAdmin()) {
534            parent :: processAdminUI();
535
536            // If no file was uploaded, update filename and mime type
537            if (!empty ($_REQUEST["file_mode".$this->getId()])) {
538                if (!empty($_REQUEST["file_file_name".$this->getId()])) {
539                    $this->setFilename($_REQUEST["file_file_name".$this->getId()]);
540                }
541
542                $file_mode = $_REQUEST["file_mode".$this->getId()];
543
544                if ($file_mode == "by_upload") {
545                    if(isset($_REQUEST["file_mime_type".$this->getId()])) {
546                        $this->setMimeType($_REQUEST["file_mime_type".$this->getId()]);
547                    }
548
549                    $this->setBinaryDataFromPostVar("file_file_upload".$this->getId());
550                    $this->setURL(null);
551
552                    // Reset the remote file size ( not used )
553                    $this->setRemoteFileSize(0);
554                } else {
555                    if ($file_mode == "remote") {
556                        $this->setURL($_REQUEST["file_url".$this->getId()]);
557                        $this->setBinaryDataOid(null);
558
559                        // When switching from local to remote, this field does not exist yet
560                        if (isset($_REQUEST["file_old_remote_size".$this->getId()])) {
561                            if ($_REQUEST["file_remote_size".$this->getId()] != $_REQUEST["file_old_remote_size".$this->getId()]) {
562                                $this->setRemoteFileSize($_REQUEST["file_remote_size".$this->getId()]);
563                            }
564                        } else {
565                            $this->setRemoteFileSize(0);
566                        }
567                    }
568                }
569            }
570        }
571    }
572
573    /**
574     * Retreives the user interface of this object.
575     *
576     * @return string The HTML fragment for this interface
577     */
578    public function getUserUI()
579    {
580        // Init values
581        $html = '';
582
583        $html .= "<div class='user_ui_container ".get_class($this)."'>\n";
584
585        if($this->getFileSize() > 0) {
586            $append_size = " (".$this->getFileSize(self :: UNIT_KILOBYTES)." "._("KB").")";
587        } else {
588            $append_size = "";
589        }
590
591        $html .= "<div class='download_button'><a href='".htmlentities($this->getFileUrl())."'>"._("Download")." ".$this->getFilename()."$append_size</a></div>";
592        $html .= "</div>\n";
593
594        return parent::getUserUI($html);
595    }
596
597    /**
598     * Reloads the object from the database. Should normally be called after
599     * a set operation. This function is private because calling it from a
600     * subclass will call the constructor from the wrong scope.
601     *
602     * @return void
603     */
604    private function refresh()
605    {
606        $this->__construct($this->id);
607    }
608
609    /**
610     * Deletes a File object
611     *
612     * @param string $errmsg Reference to error message
613     *
614     * @return bool True if deletion was successful
615     * @internal Persistent content will not be deleted
616     */
617    public function delete(&$errmsg)
618    {
619        if ($this->isPersistent() == false) {
620            // Unlink BLOB if any exists
621            $blob_oid = $this->getBinaryDataOid();
622
623            if($blob_oid) {
624                $errmsg = "Deleting BLOB OID : $blob_oid";
625
626                if($this->mBd->UnlinkLargeObject($blob_oid) == false) {
627                    $errmsg = _("Unable to successfully unlink BLOB OID : $blob_oid !");
628                    return false;
629                }
630            }
631
632            $this->mBd->execSqlUpdate("DELETE FROM content_file WHERE files_id = '".$this->getId()."'", false);
633        } else {
634            $errmsg = _("Could not delete this file, since it is persistent");
635        }
636
637        return parent::delete($errmsg);
638    }
639
640}
641
642/*
643 * Local variables:
644 * tab-width: 4
645 * c-basic-offset: 4
646 * c-hanging-comment-ender-p: nil
647 * End:
648 */
649
650
Note: See TracBrowser for help on using the browser.