<?php /** * Provides the file class, an interface to the file table in the database * * @author Camil Staps * * BusinessAdmin: administrative software for small companies * Copyright (C) 2015 Camil Staps (ViviSoft) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ /** * An interface to the file table in the database */ class File extends Model { /** {@inheritDoc} */ public static $table = 'file', $fillable_columns = ['filename', 'secret_key']; /** * {@inheritDoc} * @param PDO $pdo {@inheritDoc} * @param mixed[] $values {@inheritDoc} */ public static function create($pdo, $values) { $filename = $values[0]; // Check for file existence if (file_exists(Constants::files_folder . $filename)) { throw new Exception("$filename already exists."); } // Try to create the file if (file_put_contents(Constants::files_folder . $filename, '') === false) { throw new Exception("$filename could not be created. Check the permissions."); } if (count($values) < count(static::$fillable_columns)) { $values[] = self::getRandomSecretKey(); } return parent::create($pdo, $values); } /** * A random max-63-char string that can be used as secret_key * * @return string The random string */ public static function getRandomSecretKey() { return preg_replace('/[^\w]+/', '', base64_encode(openssl_random_pseudo_bytes(45))); } /** * Get the full internal path to the file * * @see file::getFilenameURI To get the full external path to the file * * @return string The path */ public function getFilenamePath() { return Constants::files_folder . $this->filename; } /** * Get the full external path to the file * * @see file::getFilenamePath To get the full internal path to the file * * @return string The URI */ public function getFilenameURI() { return Constants::url_external . 'file/get?name=' . $this->filename . '&key=' . $this->secret_key; } //------------------------------------------------------------------------------ // Other functions //------------------------------------------------------------------------------ /** * Move this file to the trash and delete all records for it * * Physically, this moves the file to a trash folder * Then, the file will be removed from the file table in the database * Any appendices linking to this file with fileId will have fileId NULL * Any offers linking to this file with invoice_fileId will have invoice_fileId NULL * * @throws PDOException If there's something wrong with the database * * @return bool True on success, false on failure */ public function delete() { // Try to move the file to trash $newname = pathinfo($this->filename, PATHINFO_FILENAME) . '--' . date('Y-m-d.H.i.s.') . pathinfo($this->filename, PATHINFO_EXTENSION); $newdir = pathinfo($this->getFilenamePath(), PATHINFO_DIRNAME) . '/' . Constants::files_folder_trash . '/'; if (!file_exists($newdir)) { if (!mkdir($newdir)) { return false; } } if (!(@rename($this->getFilenamePath(), $newdir . $newname))) { return false; } // Remove offers linked by invoice_fileId $this->pdo->query("UPDATE `".Constants::db_prefix."offer` SET `invoice_fileId`=NULL WHERE `invoice_fileId`={$this->id}"); return parent::delete(); } }