芝麻web文件管理V1.00
编辑当前文件:/home/mgatv524/public_html/avenida/views/Helper.zip
PK ӠqYF$kK kK Install.phpnu [ . */ namespace Xibo\Helper; use Phinx\Console\PhinxApplication; use Phinx\Wrapper\TextWrapper; use Xibo\Exception\InstallationError; use Xibo\Service\ConfigService; use Xibo\Service\SanitizerServiceInterface; use Xibo\Service\SanitizeService; use Xibo\Storage\StorageServiceInterface; /** * Class Install * @package Xibo\Helper */ class Install { // DB Details public $db_create; public $db_admin_user; public $db_admin_pass; public $new_db_host; public $new_db_user; public $new_db_pass; public $new_db_name; public $existing_db_host; public $existing_db_user; public $existing_db_pass; public $existing_db_name; /** @var SanitizerServiceInterface */ private $sanitizer; /** * Install constructor. * @param SanitizeService $sanitizer */ public function __construct($sanitizer) { $this->sanitizer = $sanitizer; } /** * @return array */ public function Step1() { return [ 'config' => new ConfigService() ]; } /** * @return array */ public function Step2() { return []; } /** * @param StorageServiceInterface $store * @throws InstallationError */ public function Step3($store) { // Have we been told to create a new database $this->db_create = $this->sanitizer->getInt('db_create'); // Check all parameters have been specified $this->db_admin_user = $this->sanitizer->getString('admin_username'); $this->db_admin_pass = $this->sanitizer->getString('admin_password'); $this->new_db_host = $this->sanitizer->getString('host'); $this->new_db_user = $this->sanitizer->getString('db_username'); $this->new_db_pass = $this->sanitizer->getString('db_password'); $this->new_db_name = $this->sanitizer->getString('db_name'); $this->existing_db_host = $this->sanitizer->getString('existing_host'); $this->existing_db_user = $this->sanitizer->getString('existing_db_username'); $this->existing_db_pass = $this->sanitizer->getString('existing_db_password'); $this->existing_db_name = $this->sanitizer->getString('existing_db_name'); // If an administrator user name / password has been specified then we should create a new DB if ($this->db_create == 1) { // Check details for a new database if ($this->new_db_host == '') throw new InstallationError(__('Please provide a database host. This is usually localhost.')); if ($this->new_db_user == '') throw new InstallationError(__('Please provide a user for the new database.')); if ($this->new_db_pass == '') throw new InstallationError(__('Please provide a password for the new database.')); if ($this->new_db_name == '') throw new InstallationError(__('Please provide a name for the new database.')); if ($this->db_admin_user == '') throw new InstallationError(__('Please provide an admin user name.')); // Try to create the new database // Try and connect using these details and create the new database try { $store->connect($this->new_db_host, $this->db_admin_user, $this->db_admin_pass); } catch (\PDOException $e) { throw new InstallationError(sprintf(__('Could not connect to MySQL with the administrator details. Please check and try again. Error Message = [%s]'), $e->getMessage())); } // Try to create the new database try { $dbh = $store->getConnection(); $dbh->exec(sprintf('CREATE DATABASE `%s` CHARACTER SET utf8 COLLATE utf8_general_ci', $this->new_db_name)); } catch (\PDOException $e) { throw new InstallationError(sprintf(__('Could not create a new database with the administrator details [%s]. Please check and try again. Error Message = [%s]'), $this->db_admin_user, $e->getMessage())); } // Try to create the new user try { $dbh = $store->getConnection(); // Create the user and grant privileges if ($this->new_db_host == 'localhost') { $sql = sprintf('GRANT ALL PRIVILEGES ON `%s`.* to %s@%s IDENTIFIED BY %s', $this->new_db_name, $dbh->quote($this->new_db_user), $dbh->quote($this->new_db_host), $dbh->quote($this->new_db_pass) ); $dbh->exec($sql); } else { $sql = sprintf('GRANT ALL PRIVILEGES ON `%s`.* to %s@\'%%\' IDENTIFIED BY %s', $this->new_db_name, $dbh->quote($this->new_db_user), $dbh->quote($this->new_db_pass) ); $dbh->exec($sql); } // Flush $dbh->exec('FLUSH PRIVILEGES'); } catch (\PDOException $e) { throw new InstallationError(sprintf(__('Could not create a new user with the administrator details. Please check and try again. Error Message = [%s]. SQL = [%s].'), $e->getMessage(), $sql)); } // Set our DB details $this->existing_db_host = $this->new_db_host; $this->existing_db_user = $this->new_db_user; $this->existing_db_pass = $this->new_db_pass; $this->existing_db_name = $this->new_db_name; // Close the connection $store->close(); } else { // Check details for a new database if ($this->existing_db_host == '') throw new InstallationError(__('Please provide a database host. This is usually localhost.')); if ($this->existing_db_user == '') throw new InstallationError(__('Please provide a user for the existing database.')); if ($this->existing_db_pass == '') throw new InstallationError(__('Please provide a password for the existing database.')); if ($this->existing_db_name == '') throw new InstallationError(__('Please provide a name for the existing database.')); } // Try and make a connection with this database try { $store->connect($this->existing_db_host, $this->existing_db_user, $this->existing_db_pass, $this->existing_db_name); } catch (\PDOException $e) { throw new InstallationError(sprintf(__('Could not connect to MySQL with the administrator details. Please check and try again. Error Message = [%s]'), $e->getMessage())); } // Write out a new settings.php $fh = fopen(PROJECT_ROOT . '/web/settings.php', 'wt'); if (!$fh) throw new InstallationError(__('Unable to write to settings.php. We already checked this was possible earlier, so something changed.')); // Get the settings template and issue replacements $settings = $this->getSettingsTemplate(); // Replace instances of $_SERVER vars with our own $settings = str_replace('$_SERVER[\'MYSQL_HOST\'] . \':\' . $_SERVER[\'MYSQL_PORT\']', '\'' . $this->existing_db_host . '\'', $settings); $settings = str_replace('$_SERVER[\'MYSQL_USER\']', '\'' . $this->existing_db_user . '\'', $settings); $settings = str_replace('$_SERVER[\'MYSQL_PASSWORD\']', '\'' . addslashes($this->existing_db_pass) . '\'', $settings); $settings = str_replace('$_SERVER[\'MYSQL_DATABASE\']', '\'' . $this->existing_db_name . '\'', $settings); $settings = str_replace('define(\'SECRET_KEY\',\'\')', 'define(\'SECRET_KEY\',\'' . Install::generateSecret() . '\');', $settings); if (!fwrite($fh, $settings)) throw new InstallationError(__('Unable to write to settings.php. We already checked this was possible earlier, so something changed.')); fclose($fh); // Run phinx migrate $phinx = new TextWrapper(new PhinxApplication(), ['configuration' => PROJECT_ROOT . '/phinx.php']); $phinx->getMigrate(); // If we get here, we want to move on to the next step. // This is handled by the calling function (i.e. there is no output from this call, we just reload and move on) } /** * @return array */ public function Step4() { return []; } /** * @param StorageServiceInterface $store * @throws InstallationError */ public function Step5($store) { // Configure the user account $username = $this->sanitizer->getString('admin_username'); $password = $this->sanitizer->getString('admin_password'); if ($username == '') throw new InstallationError(__('Missing the admin username.')); if ($password == '') throw new InstallationError(__('Missing the admin password.')); // Update user id 1 with these details. try { $dbh = $store->getConnection(); $sth = $dbh->prepare('UPDATE `user` SET UserName = :username, UserPassword = :password WHERE UserID = 1 LIMIT 1'); $sth->execute(array( 'username' => $username, 'password' => md5($password) )); // Update group ID 3 with the user name $sth = $dbh->prepare('UPDATE `group` SET `group` = :username WHERE groupId = 3 LIMIT 1'); $sth->execute(array( 'username' => $username )); } catch (\PDOException $e) { throw new InstallationError(sprintf(__('Unable to set the user details. This is an unexpected error, please contact support. Error Message = [%s]'), $e->getMessage())); } } /** * @return array */ public function Step6() { return [ 'serverKey' => Install::generateSecret(6) ]; } /** * @param StorageServiceInterface $store * @throws InstallationError */ public function Step7($store) { $server_key = $this->sanitizer->getString('server_key'); $library_location = $this->sanitizer->getString('library_location'); $stats = $this->sanitizer->getCheckbox('stats'); if ($server_key == '') throw new InstallationError(__('Missing the server key.')); if ($library_location == '') throw new InstallationError(__('Missing the library location.')); // Remove trailing white space from the path given. $library_location = trim($library_location); if (!is_dir($library_location)) { // Make sure they haven't given a file as the library location if (is_file($library_location)) throw new InstallationError(__('A file exists with the name you gave for the Library Location. Please choose another location')); // Directory does not exist. Attempt to make it // Using mkdir recursively, so it will attempt to make any // intermediate folders required. if (!mkdir($library_location, 0755, true)) { throw new InstallationError(__('Could not create the Library Location directory for you. Please ensure the webserver has permission to create a folder in this location, or create the folder manually and grant permission for the webserver to write to the folder.')); } } // Is library_location writable? if (!is_writable($library_location)) throw new InstallationError(__('The Library Location you gave is not writable by the webserver. Please fix the permissions and try again.')); // Is library_location empty? if (count(Install::ls("*", $library_location, true)) > 0) throw new InstallationError(__('The Library Location you gave is not empty. Please give the location of an empty folder')); // Check if the user has added a trailing slash. If not, add one. if (!((substr($library_location, -1) == '/') || (substr($library_location, -1) == '\\'))) { $library_location = $library_location . '/'; } try { $dbh = $store->getConnection(); // Library Location $sth = $dbh->prepare('UPDATE `setting` SET `value` = :value WHERE `setting`.`setting` = \'LIBRARY_LOCATION\' LIMIT 1'); $sth->execute(array('value' => $library_location)); // Server Key $sth = $dbh->prepare('UPDATE `setting` SET `value` = :value WHERE `setting`.`setting` = \'SERVER_KEY\' LIMIT 1'); $sth->execute(array('value' => $server_key)); // Default Time zone $sth = $dbh->prepare('UPDATE `setting` SET `value` = :value WHERE `setting`.`setting` = \'defaultTimezone\' LIMIT 1'); $sth->execute(array('value' => date_default_timezone_get())); // Phone Home $sth = $dbh->prepare('UPDATE `setting` SET `value` = :value WHERE `setting`.`setting` = \'PHONE_HOME\' LIMIT 1'); $sth->execute(array('value' => (($stats == 1) ? 'On' : 'Off'))); // Phone Home Key $sth = $dbh->prepare('UPDATE `setting` SET `value` = :value WHERE `setting`.`setting` = \'PHONE_HOME_KEY\' LIMIT 1'); $sth->execute(array('value' => md5(uniqid(rand(), true)))); } catch (\PDOException $e) { throw new InstallationError(sprintf(__('An error occurred updating these settings. This is an unexpected error, please contact support. Error Message = [%s]'), $e->getMessage())); } // Delete install if (!@unlink('index.php')) throw new InstallationError(__("Unable to delete install/index.php. Please ensure the web server has permission to unlink this file and retry")); } /** * This function will take a pattern and a folder as the argument and go thru it(recursively if needed)and return the list of * all files in that folder. * Link : http://www.bin-co.com/php/scripts/filesystem/ls/ * License : BSD * Arguments : $pattern - The pattern to look out for [OPTIONAL] * $folder - The path of the directory of which's directory list you want [OPTIONAL] * $recursivly - The funtion will traverse the folder tree recursivly if this is true. Defaults to false. [OPTIONAL] * $options - An array of values 'return_files' or 'return_folders' or both * Returns : A flat list with the path of all the files(no folders) that matches the condition given. */ public static function ls($pattern = "*", $folder = "", $recursivly = false, $options = array('return_files', 'return_folders')) { if ($folder) { $current_folder = realpath('.'); if (in_array('quiet', $options)) { // If quiet is on, we will suppress the 'no such folder' error if (!file_exists($folder)) return array(); } if (!chdir($folder)) return array(); } $get_files = in_array('return_files', $options); $get_folders = in_array('return_folders', $options); $both = array(); $folders = array(); // Get the all files and folders in the given directory. if ($get_files) $both = glob($pattern, GLOB_BRACE + GLOB_MARK); if ($recursivly or $get_folders) $folders = glob("*", GLOB_ONLYDIR + GLOB_MARK); //If a pattern is specified, make sure even the folders match that pattern. $matching_folders = array(); if ($pattern !== '*') $matching_folders = glob($pattern, GLOB_ONLYDIR + GLOB_MARK); //Get just the files by removing the folders from the list of all files. $all = array_values(array_diff($both, $folders)); if ($recursivly or $get_folders) { foreach ($folders as $this_folder) { if ($get_folders) { //If a pattern is specified, make sure even the folders match that pattern. if ($pattern !== '*') { if (in_array($this_folder, $matching_folders)) array_push($all, $this_folder); } else array_push($all, $this_folder); } if ($recursivly) { // Continue calling this function for all the folders $deep_items = Install::ls($pattern, $this_folder, $recursivly, $options); # :RECURSION: foreach ($deep_items as $item) { array_push($all, $this_folder . $item); } } } } if ($folder) chdir($current_folder); return $all; } /** * @param int $length * @return string */ public static function generateSecret($length = 12) { # Generates a random 12 character alphanumeric string to use as a salt mt_srand((double)microtime() * 1000000); $key = ""; for ($i = 0; $i < $length; $i++) { $c = mt_rand(0, 2); if ($c == 0) { $key .= chr(mt_rand(65, 90)); } elseif ($c == 1) { $key .= chr(mt_rand(97, 122)); } else { $key .= chr(mt_rand(48, 57)); } } return $key; } private function getSettingsTemplate() { return <<
" . __("Please press the back button in your browser.")); global \$dbhost; global \$dbuser; global \$dbpass; global \$dbname; \$dbhost = \$_SERVER['MYSQL_HOST'] . ':' . \$_SERVER['MYSQL_PORT']; \$dbuser = \$_SERVER['MYSQL_USER']; \$dbpass = \$_SERVER['MYSQL_PASSWORD']; \$dbname = \$_SERVER['MYSQL_DATABASE']; if (!defined('SECRET_KEY')) define('SECRET_KEY',''); if (file_exists('/var/www/cms/custom/settings-custom.php')) include_once('/var/www/cms/custom/settings-custom.php'); END; } }PK ӠqY߆D D Environment.phpnu [ . */ namespace Xibo\Helper; use Phinx\Console\PhinxApplication; use Phinx\Wrapper\TextWrapper; /** * Class Environment * @package Xibo\Helper */ class Environment { public static $WEBSITE_VERSION_NAME = '2.3.7'; public static $XMDS_VERSION = '5'; public static $XLF_VERSION = 3; public static $VERSION_REQUIRED = '7.0.8'; public static $VERSION_UNSUPPORTED = '8.0'; /** @var null cache migration status for the whole request */ private static $_migration_status = null; /** * Is there a migration pending? * @return bool */ public static function migrationPending() { return (self::getMigrationStatus() != 0); } /** * Get Migration Status * @return int */ private static function getMigrationStatus() { if (self::$_migration_status === null) { // Use a Phinx text wrapper to work out what the current status is // make sure this does not output anything to our output buffer ob_start(); $phinx = new TextWrapper(new PhinxApplication(), ['configuration' => PROJECT_ROOT . '/phinx.php']); $phinx->getStatus(); self::$_migration_status = $phinx->getExitCode(); ob_end_clean(); } return self::$_migration_status; } /** * Check FileSystem Permissions * @return bool */ public static function checkSettingsFileSystemPermissions() { $settingsPath = PROJECT_ROOT . '/web/settings.php'; return (file_exists($settingsPath)) ? is_writable($settingsPath) : is_writable(PROJECT_ROOT . '/web'); } /** * Check FileSystem Permissions * @return bool */ public static function checkCacheFileSystemPermissions() { return is_writable(PROJECT_ROOT . '/cache'); } /** * Check PHP version is within the preset parameters * @return bool */ public static function checkPHP() { return (version_compare(phpversion(), self::$VERSION_REQUIRED) != -1) && (version_compare(phpversion(), self::$VERSION_UNSUPPORTED) != 1); } /** * Check PHP has the PDO module installed (with MySQL driver) */ public static function checkPDO() { return extension_loaded("pdo_mysql"); } /** * Check PHP has the GetText module installed * @return bool */ public static function checkGettext() { return extension_loaded("gettext"); } /** * Check PHP has JSON module installed * @return bool */ public static function checkJson() { return extension_loaded("json"); } /** * * Check PHP has SOAP module installed * @return bool */ public static function checkSoap() { return extension_loaded("soap"); } /** * Check PHP has GD module installed * @return bool */ public static function checkGd() { return extension_loaded("gd"); } /** * Check PHP has the DOM XML functionality installed * @return bool */ public static function checkDomXml() { return extension_loaded("dom"); } /** * Check PHP has the DOM functionality installed * @return bool */ public static function checkDom() { return class_exists("DOMDocument"); } /** * Check PHP has session functionality installed * @return bool */ public static function checkSession() { return extension_loaded("session"); } /** * Check PHP has PCRE functionality installed * @return bool */ public static function checkPCRE() { return extension_loaded("pcre"); } /** * Check PHP has FileInfo functionality installed * @return bool */ public static function checkFileInfo() { return extension_loaded("fileinfo"); } public static function checkZip() { return extension_loaded('zip'); } public static function checkIntlDateFormat() { return class_exists('IntlDateFormatter'); } /** * Check to see if curl is installed */ public static function checkCurlInstalled() { return function_exists('curl_version'); } /** * Check PHP is setup for large file uploads * @return bool */ public static function checkPHPUploads() { # Consider 0 - 128M warning / < 120 seconds # Variables to check: # post_max_size # upload_max_filesize # max_execution_time $minSize = ByteFormatter::toBytes('128M'); if (ByteFormatter::toBytes(ini_get('post_max_size')) < $minSize) return false; if (ByteFormatter::toBytes(ini_get('upload_max_filesize')) < $minSize) return false; if (ini_get('max_execution_time') < 120) return false; // All passed return true; } /** * @inheritdoc */ public static function checkZmq() { return class_exists('ZMQSocket'); } public static function getMaxUploadSize() { return ini_get('upload_max_filesize'); } /** * Check open ssl is available * @return bool */ public static function checkOpenSsl() { return extension_loaded('openssl'); } /** * @inheritdoc * https://stackoverflow.com/a/45767760 */ public static function getMemoryLimitBytes() { return intval(str_replace(array('G', 'M', 'K'), array('000000000', '000000', '000'), ini_get('memory_limit'))); } /** * @return bool */ public static function checkTimezoneIdentifiers() { return function_exists('timezone_identifiers_list'); } /** * @return bool */ public static function checkAllowUrlFopen() { return ini_get('allow_url_fopen'); } /** * @return bool */ public static function checkSimpleXml() { return extension_loaded('simplexml'); } /** * @param $url * @return bool */ public static function checkUrl($url) { return (stripos($url, '/web/') === false); } /** * Is the CMS in DEV mode? * @return bool */ public static function isDevMode() { return (isset($_SERVER['CMS_DEV_MODE']) && $_SERVER['CMS_DEV_MODE'] === 'true'); } /** * Is debugging forced ON for this request? * @return bool */ public static function isForceDebugging() { return (isset($_SERVER['CMS_FORCE_DEBUG']) && $_SERVER['CMS_FORCE_DEBUG'] === 'true'); } }PK ӠqYɩ ByteFormatter.phpnu [ getScheme() . '://' . $this->getHost(); if (($this->getScheme() === 'https' && $this->getPort() !== 443) || ($this->getScheme() === 'http' && $this->getPort() !== 80)) { $url .= sprintf(':%s', $this->getPort()); } return $url; } /** * @return string */ public function getScheme() { return ($this->isHttps()) ? 'https' : 'http'; } /** * Get Host * @return string */ public function getHost() { if (isset($_SERVER['HTTP_HOST'])) { if (strpos($_SERVER['HTTP_HOST'], ':') !== false) { $hostParts = explode(':', $_SERVER['HTTP_HOST']); return $hostParts[0]; } return $_SERVER['HTTP_HOST']; } return $_SERVER['SERVER_NAME']; } /** * Get Port * @return int */ public function getPort() { if (isset($_SERVER['HTTP_HOST']) && strpos($_SERVER['HTTP_HOST'], ':') !== false) { $hostParts = explode(':', $_SERVER['HTTP_HOST']); return $hostParts[1]; } return ($this->isHttps() ? 443 : 80); } /** * Is HTTPs? * @return bool */ public function isHttps() { return ( (isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on') || (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) == 'https') ); } }PK ӠqYE3 E3 Session.phpnu [ . */ namespace Xibo\Helper; use Xibo\Service\LogService; use Xibo\Storage\PdoStorageService; /** * Class Session * @package Xibo\Helper */ class Session implements \SessionHandlerInterface { private $maxLifetime; private $key; /** * Refresh expiry * @var bool */ public $refreshExpiry = true; /** * Expiry time * @var int */ private $sessionExpiry = 0; /** * Is the session expired? * @var bool */ private $expired = true; /** * The UserId whom owns this session * @var int */ private $userId = 0; /** * @var bool Whether gc() has been called */ private $gcCalled = false; /** * Prune this key? * @var bool */ private $pruneKey = false; /** * The database connection * @var PdoStorageService */ private $pdo = null; /** * Log * @var LogService */ private $log; /** * Session constructor. * @param LogService $log */ function __construct($log) { $this->log = $log; session_set_save_handler( array(&$this, 'open'), array(&$this, 'close'), array(&$this, 'read'), array(&$this, 'write'), array(&$this, 'destroy'), array(&$this, 'gc') ); register_shutdown_function('session_write_close'); // Start the session session_cache_limiter(false); session_start(); } /** * {@inheritdoc} */ public function open($savePath, $sessionName) { //$this->log->debug('Session open'); $this->maxLifetime = ini_get('session.gc_maxlifetime'); return true; } /** * {@inheritdoc} */ public function close() { //$this->log->debug('Session close'); try { // Commit $this->commit(); } catch (\PDOException $e) { $this->log->error('Error closing session: %s', $e->getMessage()); } try { // Prune this session if necessary if ($this->pruneKey || $this->gcCalled) { $db = new PdoStorageService($this->log); $db->setConnection(); if ($this->pruneKey) { $db->update('DELETE FROM `session` WHERE session_id = :session_id', array('session_id' => $this->key)); } if ($this->gcCalled) { // Delete sessions older than 10 times the max lifetime $db->update('DELETE FROM `session` WHERE IsExpired = 1 AND session_expiration < :expiration', array('expiration' => (time() - ($this->maxLifetime * 10)))); // Update expired sessions as expired $db->update('UPDATE `session` SET IsExpired = 1 WHERE session_expiration < :expiration', array('expiration' => time())); } $db->commitIfNecessary(); $db->close(); } } catch (\PDOException $e) { $this->log->error('Error closing session: %s', $e->getMessage()); } // Close $this->getDb()->close(); return true; } /** * {@inheritdoc} */ function read($key) { //$this->log->debug('Session read'); $data = ''; $this->key = $key; $userAgent = substr($_SERVER['HTTP_USER_AGENT'], 0, 253); try { $dbh = $this->getDb(); // Start a transaction $this->beginTransaction(); // Get this session $sth = $dbh->getConnection()->prepare(' SELECT `session_data`, `isexpired`, `useragent`, `session_expiration`, `userId` FROM `session` WHERE `session_id` = :session_id '); $sth->execute(['session_id' => $key]); if (!$row = $sth->fetch()) { // New session. $this->insertSession($key, '', time(), time() + $this->maxLifetime); $this->expired = false; } else { // Existing session // Check the session hasn't expired if ($row['session_expiration'] < time()) $this->expired = true; else $this->expired = $row['isexpired']; // What happens if the UserAgent has changed? if ($row['useragent'] != $userAgent) { // Force delete this session $this->expired = 1; $this->pruneKey = true; } $this->userId = $row['userId']; $this->sessionExpiry = $row['session_expiration']; // Set the session data (expired or not) $data = $row['session_data']; } return (string)$data; } catch (\Exception $e) { $this->log->error('Error reading session: %s', $e->getMessage()); return (string)$data; } } /** * {@inheritdoc} */ public function write($key, $val) { //$this->log->debug('Session write'); // What should we do with expiry? $expiry = ($this->refreshExpiry) ? time() + $this->maxLifetime : $this->sessionExpiry; try { $this->updateSession($key, $val, time(), $expiry); } catch (\PDOException $e) { $this->log->error('Error writing session data: %s', $e->getMessage()); return false; } return true; } /** * {@inheritdoc} */ public function destroy($key) { //$this->log->debug('Session destroy'); try { $this->getDb()->update('DELETE FROM `session` WHERE session_id = :session_id', ['session_id' => $key]); } catch (\PDOException $e) { $this->log->error('Error destroying session: %s', $e->getMessage()); } return true; } /** * {@inheritdoc} */ public function gc($maxLifetime) { //$this->log->debug('Session gc'); $this->gcCalled = true; return true; } /** * Sets the User Id * @param $userId */ public function setUser($userId) { //$this->log->debug('Setting user Id to %d', $userId); $_SESSION['userid'] = $userId; $this->userId = $userId; } /** * Updates the session ID with a new one */ public function regenerateSessionId() { //$this->log->debug('Session regenerate'); session_regenerate_id(true); $this->key = session_id(); // PHP7 calls open/close on regenerate // PHP5 does neither if (version_compare(phpversion(), '7.0') === -1) { $this->insertSession($this->key, '', time(), time() + $this->maxLifetime); } } /** * Set this session to expired * @param $isExpired */ public function setIsExpired($isExpired) { $this->expired = $isExpired; } /** * Store a variable in the session * @param string $key * @param mixed $secondKey * @param mixed|null $value * @return mixed */ public static function set($key, $secondKey, $value = null) { if (func_num_args() == 2) { $_SESSION[$key] = $secondKey; return $secondKey; } else { if (!isset($_SESSION[$key]) || !is_array($_SESSION[$key])) $_SESSION[$key] = []; $_SESSION[$key][(string) $secondKey] = $value; return $value; } } /** * Get the Value from the position denoted by the 2 keys provided * @param string $key * @param string [Optional] $secondKey * @return bool */ public static function get($key, $secondKey = NULL) { if ($secondKey != NULL) { if (isset($_SESSION[$key][$secondKey])) return $_SESSION[$key][$secondKey]; } else { if (isset($_SESSION[$key])) return $_SESSION[$key]; } return false; } /** * Is the session expired? * @return bool */ public function isExpired() { return $this->expired; } /** * Get a Database * @return PdoStorageService */ private function getDb() { if ($this->pdo == null) $this->pdo = (new PdoStorageService($this->log))->setConnection(); return $this->pdo; } /** * Helper method to begin a transaction. * * MySQLs default isolation, REPEATABLE READ, causes deadlock for different sessions * due to http://www.mysqlperformanceblog.com/2013/12/12/one-more-innodb-gap-lock-to-avoid/ . * So we change it to READ COMMITTED. */ private function beginTransaction() { if (!$this->getDb()->getConnection()->inTransaction()) { try { $this->getDb()->getConnection()->exec('SET TRANSACTION ISOLATION LEVEL READ COMMITTED'); } catch (\PDOException $e) { // https://github.com/xibosignage/xibo/issues/787 // this only works if BINLOG format is set to MIXED or ROW $this->log->error('Unable to set session transaction isolation level, message = ' . $e->getMessage()); } $this->getDb()->getConnection()->beginTransaction(); } } /** * Commit */ private function commit() { if ($this->getDb()->getConnection()->inTransaction()) $this->getDb()->getConnection()->commit(); } /** * Insert session * @param $key * @param $data * @param $lastAccessed * @param $expiry */ private function insertSession($key, $data, $lastAccessed, $expiry) { //$this->log->debug('Session insert'); $sql = ' INSERT INTO `session` (session_id, session_data, session_expiration, lastaccessed, userid, isexpired, useragent, remoteaddr) VALUES (:session_id, :session_data, :session_expiration, :lastAccessed, :userId, :expired, :useragent, :remoteaddr) '; $params = [ 'session_id' => $key, 'session_data' => $data, 'session_expiration' => $expiry, 'lastAccessed' => date('Y-m-d H:i:s', $lastAccessed), 'userId' => $this->userId, 'expired' => ($this->expired) ? 1 : 0, 'useragent' => substr($_SERVER['HTTP_USER_AGENT'], 0, 253), 'remoteaddr' => $this->getIp() ]; $this->getDb()->update($sql, $params); } /** * Update Session * @param $key * @param $data * @param $lastAccessed * @param $expiry */ private function updateSession($key, $data, $lastAccessed, $expiry) { //$this->log->debug('Session update'); $sql = ' UPDATE `session` SET session_data = :session_data, session_expiration = :session_expiration, LastAccessed = :lastAccessed, userID = :userId, IsExpired = :expired WHERE session_id = :session_id '; $params = [ 'session_data' => $data, 'session_expiration' => $expiry, 'lastAccessed' => date('Y-m-d H:i:s', $lastAccessed), 'userId' => $this->userId, 'expired' => ($this->expired) ? 1 : 0, 'session_id' => $key ]; $this->getDb()->update($sql, $params); } /** * Get the Client IP Address * @return string */ private function getIp() { $clientIp = ''; $keys = array('X_FORWARDED_FOR', 'HTTP_X_FORWARDED_FOR', 'CLIENT_IP', 'REMOTE_ADDR'); foreach ($keys as $key) { if (isset($_SERVER[$key])) { $clientIp = $_SERVER[$key]; break; } } return $clientIp; } /** * @param $userId */ public function expireAllSessionsForUser($userId) { $this->getDb()->update('UPDATE `session` SET IsExpired = 1 WHERE userID = :userId', [ 'userId' => $userId ]); } } PK ӠqYi^ ^ Random.phpnu [ . */ namespace Xibo\Helper; class ObjectVars { /** * Get Object Properties * @param $object * @return array */ public static function getObjectVars($object) { return get_object_vars($object); } }PK ӠqYn DatabaseLogHandler.phpnu [ . */ namespace Xibo\Helper; use Monolog\Handler\AbstractProcessingHandler; use Xibo\Storage\PdoStorageService; /** * Class DatabaseLogHandler * @package Xibo\Helper */ class DatabaseLogHandler extends AbstractProcessingHandler { private static $statement; protected function write(array $record) { if (self::$statement == NULL) { $pdo = PdoStorageService::newConnection(); $SQL = 'INSERT INTO log (runNo, logdate, channel, type, page, function, message, userid, displayid) VALUES (:runNo, :logdate, :channel, :type, :page, :function, :message, :userid, :displayid) '; self::$statement = $pdo->prepare($SQL); } $params = array( 'runNo' => isset($record['extra']['uid']) ? $record['extra']['uid'] : '', 'logdate' => $record['datetime']->format("Y-m-d H:i:s"), 'type' => $record['level_name'], 'channel' => $record['channel'], 'page' => isset($record['extra']['route']) ? $record['extra']['route'] : '', 'function' => isset($record['extra']['method']) ? $record['extra']['method'] : '', 'message' => $record['message'], 'userid' => isset($record['extra']['userId']) ? $record['extra']['userId'] : 0, 'displayid' => isset($record['extra']['displayId']) ? $record['extra']['displayId'] : 0 ); try { PdoStorageService::incrementStatStatic('log', 'insert'); self::$statement->execute($params); } catch (\PDOException $e) { // Not sure what we can do here? } } }PK ӠqYY Translate.phpnu [ . */ namespace Xibo\Helper; use CachedFileReader; use Gettext\Translations; use Gettext\Translator; use gettext_reader; use Illuminate\Support\Str; use Xibo\Service\ConfigServiceInterface; /** * Class Translate * @package Xibo\Helper */ class Translate { private static $requestedLanguage; private static $locale; private static $jsLocale; private static $jsLocaleRequested; /** * Gets and Sets the Locale * @param ConfigServiceInterface $config * @param $language string[optional] The Language to Load */ public static function InitLocale($config, $language = NULL) { // The default language $default = ($language === null) ? $config->getSetting('DEFAULT_LANGUAGE') : $language; // Build an array of supported languages $localeDir = PROJECT_ROOT . '/locale'; $supportedLanguages = array_map('basename', glob($localeDir . '/*.mo')); // Record any matching languages we find. $foundLanguage = null; // Try to get the local firstly from _REQUEST (post then get) if ($language != null) { // Serve only the requested language // Firstly, Sanitize it self::$requestedLanguage = str_replace('-', '_', $language); // Check its valid if (in_array(self::$requestedLanguage . '.mo', $supportedLanguages)) { $foundLanguage = self::$requestedLanguage; } } else if ($config->getSetting('DETECT_LANGUAGE') == 1) { // Detect the language, try from HTTP accept // Parse the language header and build a preference array $languagePreferenceArray = Translate::parseHttpAcceptLanguageHeader(); if (count($languagePreferenceArray) > 0) { // Go through the list until we have a match foreach ($languagePreferenceArray as $languagePreference => $preferenceRating) { // We don't ship an en.mo, so fudge in a case where we automatically convert that to en_GB if ($languagePreference == 'en') $languagePreference = 'en_GB'; // Sanitize $languagePreference = str_replace('-', '_', $languagePreference); // Set as requested self::$requestedLanguage = $languagePreference; // Check it is valid if (in_array($languagePreference . '.mo', $supportedLanguages)) { $foundLanguage = $languagePreference; break; } } } } // Requested language if (self::$requestedLanguage == null) self::$requestedLanguage = $default; // Are we still empty, then default language from settings if ($foundLanguage == '') { // Check the default if (!in_array($default . '.mo', $supportedLanguages)) { $default = 'en_GB'; } // The default is valid $foundLanguage = $default; } // Load translations $translator = new Translator(); $translator->loadTranslations(Translations::fromMoFile($localeDir . '/' . $foundLanguage . '.mo')); $translator->register(); // Store our resolved language locales self::$locale = $foundLanguage; self::$jsLocale = str_replace('_', '-', $foundLanguage); self::$jsLocaleRequested = str_replace('_', '-', self::$requestedLanguage); } /** * Get the Locale * @param null $characters The number of characters to take from the beginning of the local string * @return mixed */ public static function GetLocale($characters = null) { return ($characters == null) ? self::$locale : substr(self::$locale, 0, $characters); } public static function GetJsLocale() { return self::$jsLocale; } /** * @param array $options * @return string */ public static function getRequestedJsLocale($options = []) { $options = array_merge([ 'short' => false ], $options); if ($options['short'] && (strlen(self::$jsLocaleRequested) > 2) && Str::contains(self::$jsLocaleRequested, '-')) { // Short js-locale requested, and our string is longer than 2 characters and has a splitter (language variant) $variant = explode('-', self::$jsLocaleRequested); // The logic here is that if they are the same, i.e. de-DE, then we should only output de, but if they are // different, i.e. de-AT then we should output the whole thing return (strtolower($variant[0]) === strtolower($variant[1])) ? $variant[0] : self::$jsLocaleRequested; } else { return self::$jsLocaleRequested; } } public static function getRequestedLanguage() { return self::$requestedLanguage; } /** * Parse the HttpAcceptLanguage Header * Inspired by: http://www.thefutureoftheweb.com/blog/use-accept-language-header * @param null $header * @return array Language array where the key is the language identifier and the value is the preference double. */ public static function parseHttpAcceptLanguageHeader($header = null) { if ($header == null) $header = isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) ? $_SERVER['HTTP_ACCEPT_LANGUAGE'] : ''; $languages = array(); if ($header != '') { // break up string into pieces (languages and q factors) preg_match_all('/([a-z]{1,8}(-[a-z]{1,8})?)\s*(;\s*q\s*=\s*(1|0\.[0-9]+))?/i', $header, $langParse); if (count($langParse[1])) { // create a list like "en" => 0.8 $languages = array_combine($langParse[1], $langParse[4]); // set default to 1 for any without q factor foreach ($languages as $lang => $val) { if ($val === '') $languages[$lang] = 1; } // sort list based on value arsort($languages, SORT_NUMERIC); } } return $languages; } }PK ӠqYU ApplicationState.phpnu [ . */ namespace Xibo\Helper; /** * Class ApplicationState * @package Xibo\Helper */ class ApplicationState { public $httpStatus = 200; public $template; public $message; public $success; public $html; public $buttons; public $fieldActions; public $dialogTitle; public $callBack; public $login; public $clockUpdate; public $id; private $data; public $extra; public $recordsTotal; public $recordsFiltered; public function __construct() { // Assume success $this->success = true; $this->buttons = ''; $this->fieldActions = ''; $this->extra = array(); } /** * Sets the Default response if for a login box */ function Login() { $this->login = true; $this->success = false; } /** * Add a Field Action to a Field * @param string $field The field name * @param string $action The action name * @param string $value The value to trigger on * @param string $actions The actions (field => action) * @param string $operation The Operation (optional) */ public function addFieldAction($field, $action, $value, $actions, $operation = "equals") { $this->fieldActions[] = array( 'field' => $field, 'trigger' => $action, 'value' => $value, 'operation' => $operation, 'actions' => $actions ); } /** * Response JSON * @return string JSON String */ public function asJson() { // Construct the Response $response = array(); // General $response['html'] = $this->html; $response['buttons'] = $this->buttons; $response['fieldActions'] = $this->fieldActions; $response['dialogTitle'] = $this->dialogTitle; $response['callBack'] = $this->callBack; $response['success'] = $this->success; $response['message'] = $this->message; $response['clockUpdate'] = $this->clockUpdate; // Login $response['login'] = $this->login; // Extra $response['id'] = intval($this->id); $response['extra'] = $this->extra; $response['data'] = $this->data; return json_encode($response); } /** * Set Data * @param array $data */ public function setData($data) { $this->data = $data; } /** * Get Data * @return array|mixed */ public function getData() { if ($this->data == null) $this->data = []; return $this->data; } /** * Hydrate with properties * * @param array $properties * * @return self */ public function hydrate(array $properties) { foreach ($properties as $prop => $val) { if (property_exists($this, $prop)) { $this->{$prop} = $val; } } return $this; } } PK ӠqY- @ Pbkdf2Hash.phpnu [ . */ namespace Xibo\Helper; use QRException; use RobThree\Auth\Providers\Qr\BaseHTTPQRCodeProvider; class QuickChartQRProvider extends BaseHTTPQRCodeProvider { public $url; public $errorCorrectionLevel; public $margin; public $backgroundColor; public $color; public $format; /** * QuickChartQRProvider constructor. * @param string $url URL to a Quick Chart service * @param bool $verifyssl * @param string $errorCorrectionLevel valid values L, M, Q, H * @param int $margin * @param string $backgroundColor Hex color code - background colour * @param string $color Hex color code - QR colour * @param string $format Valid values: png, svg * @throws QRException */ function __construct($url, $verifyssl = false, $errorCorrectionLevel = 'L', $margin = 4, $backgroundColor = 'ffffff', $color = '000000', $format = 'png') { if (!is_bool($verifyssl)) { throw new QRException('VerifySSL must be bool'); } $this->verifyssl = $verifyssl; $this->url = $url; $this->errorCorrectionLevel = $errorCorrectionLevel; $this->margin = $margin; $this->backgroundColor = $backgroundColor; $this->color = $color; $this->format = $format; } /** * @return string * @throws QRException */ public function getMimeType() { switch (strtolower($this->format)) { case 'png': return 'image/png'; case 'svg': return 'image/svg+xml'; } throw new \QRException(sprintf('Unknown MIME-type: %s', $this->format)); } public function getQRCodeImage($qrText, $size) { return $this->getContent($this->getUrl($qrText, $size)); } public function getUrl($qrText, $size) { return $this->url . '/qr' . '?size=' . $size . '&ecLevel=' . strtoupper($this->errorCorrectionLevel) . '&margin=' . $this->margin . '&light=' . $this->backgroundColor . '&dark=' . $this->color . '&format=' . strtolower($this->format) . '&text=' . rawurlencode($qrText); } }PK ӠqYU* * WakeOnLan.phpnu [ 32)) { throw new \Exception(__('CIDR subnet mask is not a number within the range of 0 till 32.')); } // Convert $cidr from one decimal to one inverted binary array $inverted_binary_cidr = ""; // Build $inverted_binary_cidr by $cidr * zeros (this is the mask) for ($a=0; $a<$cidr; $a++) $inverted_binary_cidr .= "0"; // Invert the mask (by postfixing ones to $inverted_binary_cidr untill 32 bits are filled/ complete) $inverted_binary_cidr = $inverted_binary_cidr.substr("11111111111111111111111111111111", 0, 32 - strlen($inverted_binary_cidr)); // Convert $inverted_binary_cidr to an array of bits $inverted_binary_cidr_array = str_split($inverted_binary_cidr); // Convert IP address from four decimals to one binary array // Split IP address into an array of (four) decimals $addr_byte = explode('.', $address); $binary_addr = ""; for ($a=0; $a<4; $a++) { // Prefix zeros $pre = substr("00000000",0,8-strlen(decbin($addr_byte[$a]))); // Postfix binary decimal $post = decbin($addr_byte[$a]); $binary_addr .= $pre.$post; } // Convert $binary_addr to an array of bits $binary_addr_array = str_split($binary_addr); // Perform a bitwise OR operation on arrays ($binary_addr_array & $inverted_binary_cidr_array) $binary_broadcast_addr_array=""; // binary array of 32 bit variables ('|' = logical operator 'or') for ($a=0; $a<32; $a++) $binary_broadcast_addr_array[$a] = ($binary_addr_array[$a] | $inverted_binary_cidr_array[$a]); // build binary address of four bundles of 8 bits (= 1 byte) $binary_broadcast_addr = chunk_split(implode("", $binary_broadcast_addr_array), 8, "."); // chop off last dot ('.') $binary_broadcast_addr = substr($binary_broadcast_addr,0,strlen($binary_broadcast_addr)-1); // binary array of 4 byte variables $binary_broadcast_addr_array = explode(".", $binary_broadcast_addr); $broadcast_addr_array = ""; // decimal array of 4 byte variables for ($a=0; $a<4; $a++) $broadcast_addr_array[$a] = bindec($binary_broadcast_addr_array[$a]); // broadcast address $address = implode(".", $broadcast_addr_array); } // Check whether $port is valid if ((!ctype_digit($port)) || ($port < 0) || ($port > 65536)) throw new \Exception(__('Port is not a number within the range of 0 till 65536. Port Provided: ' . $port)); // Check whether UDP is supported if (!array_search('udp', stream_get_transports())) throw new \Exception(__('No magic packet can been sent, since UDP is unsupported (not a registered socket transport)')); // Ready to send the packet if (function_exists('fsockopen')) { // Try fsockopen function - To do: handle error 'Permission denied' $socket = fsockopen("udp://" . $address, $port, $errno, $errstr); if ($socket) { $socket_data = fwrite($socket, $buf); if ($socket_data) { $function = "fwrite"; $sent_fsockopen = "A magic packet of ".$socket_data." bytes has been sent via UDP to IP address: ".$address.":".$port.", using the '".$function."()' function."; $content = bin2hex($buf); $sent_fsockopen = $sent_fsockopen."Contents of magic packet:".strlen($content)." ".$content; fclose($socket); unset($socket); $logger->notice($sent_fsockopen, 'display', 'WakeOnLan'); return true; } else { unset($socket); throw new \Exception(__('Using "fwrite()" failed, due to error: ' . $errstr. ' ("' . $errno . '")')); } } else { unset($socket); $logger->notice(__('Using fsockopen() failed, due to denied permission')); } } // Try socket_create function if (function_exists('socket_create')) { // create socket based on IPv4, datagram and UDP $socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); if ($socket) { // to enable manipulation of options at the socket level (you may have to change this to 1) $level = SOL_SOCKET; // to enable permission to transmit broadcast datagrams on the socket (you may have to change this to 6) $optname = SO_BROADCAST; $optval = true; $opt_returnvalue = socket_set_option($socket, $level, $optname, $optval); if ($opt_returnvalue < 0) { throw new \Exception(__('Using "socket_set_option()" failed, due to error: ' . socket_strerror($opt_returnvalue))); } $flags = 0; // To do: handle error 'Operation not permitted' $socket_data = socket_sendto($socket, $buf, strlen($buf), $flags, $address, $port); if ($socket_data) { $function = "socket_sendto"; $socket_create = "A magic packet of ". $socket_data . " bytes has been sent via UDP to IP address: ".$address.":".$port.", using the '".$function."()' function.
"; $content = bin2hex($buf); $socket_create = $socket_create . "Contents of magic packet:" . strlen($content) ." " . $content; socket_close($socket); unset($socket); $logger->notice($socket_create, 'display', 'WakeOnLan'); return true; } else { $error = __('Using "socket_sendto()" failed, due to error: ' . socket_strerror(socket_last_error($socket)) . ' (' . socket_last_error($socket) . ')'); socket_close($socket); unset($socket); throw new \Exception($error); } } else { throw new \Exception(__('Using "socket_sendto()" failed, due to error: ' . socket_strerror(socket_last_error($socket)) . ' (' . socket_last_error($socket) . ')')); } } else { throw new \Exception(__('Wake On Lan Failed as there are no functions available to transmit it')); } } }PK ӠqY7Tb b LogProcessor.phpnu [ . */ namespace Xibo\Helper; use Slim\Slim; /** * Class LogProcessor * @package Xibo\Helper */ class LogProcessor { /** * @param array $record * @return array */ public function __invoke(array $record) { $app = Slim::getInstance(); if ($app === null) return $record; $record['extra']['method'] = $app->request()->getMethod(); $record['extra']['route'] = $app->request()->getResourceUri(); if ($app->user != null) $record['extra']['userId'] = $app->user->userId; return $record; } }PK ӠqYBQ Q BlueImpUploadHandler.phpnu [ 'The uploaded file exceeds the upload_max_filesize directive in php.ini', 2 => 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form', 3 => 'The uploaded file was only partially uploaded', 4 => 'No file was uploaded', 6 => 'Missing a temporary folder', 7 => 'Failed to write file to disk', 8 => 'A PHP extension stopped the file upload', 'post_max_size' => 'The uploaded file exceeds the post_max_size directive in php.ini', 'max_file_size' => 'File is too big', 'min_file_size' => 'File is too small', 'accept_file_types' => 'Filetype not allowed', 'max_number_of_files' => 'Maximum number of files exceeded', 'max_width' => 'Image exceeds maximum width', 'min_width' => 'Image requires a minimum width', 'max_height' => 'Image exceeds maximum height', 'min_height' => 'Image requires a minimum height' ); function __construct($options = null, $initialize = true, $error_messages = null) { $this->options = array( 'script_url' => $this->get_full_url() . '/', 'upload_dir' => dirname($this->get_server_var('SCRIPT_FILENAME')) . '/files/', 'upload_url' => $this->get_full_url() . '/files/', 'user_dirs' => false, 'mkdir_mode' => 0755, 'param_name' => 'files', // Set the following option to 'POST', if your server does not support // DELETE requests. This is a parameter sent to the client: 'delete_type' => 'DELETE', 'access_control_allow_origin' => '*', 'access_control_allow_credentials' => false, 'access_control_allow_methods' => array( 'OPTIONS', 'HEAD', 'GET', 'POST', 'PUT', 'PATCH', 'DELETE' ), 'access_control_allow_headers' => array( 'Content-Type', 'Content-Range', 'Content-Disposition' ), // Enable to provide file downloads via GET requests to the PHP script: 'download_via_php' => false, // Defines which files can be displayed inline when downloaded: 'inline_file_types' => '/\.(gif|jpe?g|png)$/i', // Defines which files (based on their names) are accepted for upload: 'accept_file_types' => '/.+$/i', // The php.ini settings upload_max_filesize and post_max_size // take precedence over the following max_file_size setting: 'max_file_size' => null, 'min_file_size' => 1, // The maximum number of files for the upload directory: 'max_number_of_files' => null, // Image resolution restrictions: 'max_width' => null, 'max_height' => null, 'min_width' => 1, 'min_height' => 1, // Set the following option to false to enable resumable uploads: 'discard_aborted_uploads' => true, // Set to true to rotate images based on EXIF meta data, if available: 'orient_image' => false, 'image_versions' => array( // Uncomment the following version to restrict the size of // uploaded images: /* '' => array( 'max_width' => 1920, 'max_height' => 1200, 'jpeg_quality' => 95 ), */ // Uncomment the following to create medium sized images: /* 'medium' => array( 'max_width' => 800, 'max_height' => 600, 'jpeg_quality' => 80 ), */ 'thumbnail' => array( // Uncomment the following to force the max // dimensions and e.g. create square thumbnails: //'crop' => true, 'max_width' => 80, 'max_height' => 80 ) ) ); if ($options) { $this->options = array_merge($this->options, $options); } if ($error_messages) { $this->error_messages = array_merge($this->error_messages, $error_messages); } if ($initialize) { $this->initialize(); } } protected function initialize() { switch ($this->get_server_var('REQUEST_METHOD')) { case 'OPTIONS': case 'HEAD': $this->head(); break; case 'GET': $this->get(); break; case 'PATCH': case 'PUT': case 'POST': $this->post(); break; case 'DELETE': $this->delete(); break; default: $this->header('HTTP/1.1 405 Method Not Allowed'); } } protected function get_full_url() { $https = !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off'; return ($https ? 'https://' : 'http://') . (!empty($_SERVER['REMOTE_USER']) ? $_SERVER['REMOTE_USER'] . '@' : '') . (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : ($_SERVER['SERVER_NAME'] . ($https && $_SERVER['SERVER_PORT'] === 443 || $_SERVER['SERVER_PORT'] === 80 ? '' : ':' . $_SERVER['SERVER_PORT']))) . substr($_SERVER['SCRIPT_NAME'], 0, strrpos($_SERVER['SCRIPT_NAME'], '/')); } protected function get_user_id() { @session_start(); return session_id(); } protected function get_user_path() { if ($this->options['user_dirs']) { return $this->get_user_id() . '/'; } return ''; } protected function get_upload_path($file_name = null, $version = null) { $file_name = $file_name ? $file_name : ''; $version_path = empty($version) ? '' : $version . '/'; return $this->options['upload_dir'] . $this->get_user_path() . $version_path . $file_name; } protected function get_query_separator($url) { return strpos($url, '?') === false ? '?' : '&'; } protected function get_download_url($file_name, $version = null) { if ($this->options['download_via_php']) { $url = $this->options['script_url'] . $this->get_query_separator($this->options['script_url']) . 'file=' . rawurlencode($file_name); if ($version) { $url .= '&version=' . rawurlencode($version); } return $url . '&download=1'; } $version_path = empty($version) ? '' : rawurlencode($version) . '/'; return $this->options['upload_url'] . $this->get_user_path() . $version_path . rawurlencode($file_name); } protected function set_file_delete_properties($file) { $file->delete_url = $this->options['script_url'] . $this->get_query_separator($this->options['script_url']) . 'file=' . rawurlencode($file->name); $file->delete_type = $this->options['delete_type']; if ($file->delete_type !== 'DELETE') { $file->delete_url .= '&_method=DELETE'; } if ($this->options['access_control_allow_credentials']) { $file->delete_with_credentials = true; } } // Fix for overflowing signed 32 bit integers, // works for sizes up to 2^32-1 bytes (4 GiB - 1): protected function fix_integer_overflow($size) { if ($size < 0) { $size += 2.0 * (PHP_INT_MAX + 1); } return $size; } protected function get_file_size($file_path, $clear_stat_cache = false) { if ($clear_stat_cache) { clearstatcache(true, $file_path); } return $this->fix_integer_overflow(filesize($file_path)); } protected function is_valid_file_object($file_name) { $file_path = $this->get_upload_path($file_name); if (is_file($file_path) && $file_name[0] !== '.') { return true; } return false; } protected function get_file_object($file_name) { if ($this->is_valid_file_object($file_name)) { $file = new stdClass(); $file->name = $file_name; $file->size = $this->get_file_size( $this->get_upload_path($file_name) ); $file->url = $this->get_download_url($file->name); foreach ($this->options['image_versions'] as $version => $options) { if (!empty($version)) { if (is_file($this->get_upload_path($file_name, $version))) { $file->{$version . '_url'} = $this->get_download_url( $file->name, $version ); } } } $this->set_file_delete_properties($file); return $file; } return null; } protected function get_file_objects($iteration_method = 'get_file_object') { $upload_dir = $this->get_upload_path(); if (!is_dir($upload_dir)) { return array(); } return array_values(array_filter(array_map( array($this, $iteration_method), scandir($upload_dir) ))); } protected function count_file_objects() { return count($this->get_file_objects('is_valid_file_object')); } protected function create_scaled_image($file_name, $version, $options) { $file_path = $this->get_upload_path($file_name); if (!empty($version)) { $version_dir = $this->get_upload_path(null, $version); if (!is_dir($version_dir)) { mkdir($version_dir, $this->options['mkdir_mode'], true); } $new_file_path = $version_dir . '/' . $file_name; } else { $new_file_path = $file_path; } if (!function_exists('getimagesize')) { error_log('Function not found: getimagesize'); return false; } list($img_width, $img_height) = @getimagesize($file_path); if (!$img_width || !$img_height) { return false; } $max_width = $options['max_width']; $max_height = $options['max_height']; $scale = min( $max_width / $img_width, $max_height / $img_height ); if ($scale >= 1) { if ($file_path !== $new_file_path) { return copy($file_path, $new_file_path); } return true; } if (!function_exists('imagecreatetruecolor')) { error_log('Function not found: imagecreatetruecolor'); return false; } if (empty($options['crop'])) { $new_width = $img_width * $scale; $new_height = $img_height * $scale; $dst_x = 0; $dst_y = 0; $new_img = @imagecreatetruecolor($new_width, $new_height); } else { if (($img_width / $img_height) >= ($max_width / $max_height)) { $new_width = $img_width / ($img_height / $max_height); $new_height = $max_height; } else { $new_width = $max_width; $new_height = $img_height / ($img_width / $max_width); } $dst_x = 0 - ($new_width - $max_width) / 2; $dst_y = 0 - ($new_height - $max_height) / 2; $new_img = @imagecreatetruecolor($max_width, $max_height); } switch (strtolower(substr(strrchr($file_name, '.'), 1))) { case 'jpg': case 'jpeg': $src_img = @imagecreatefromjpeg($file_path); $write_image = 'imagejpeg'; $image_quality = isset($options['jpeg_quality']) ? $options['jpeg_quality'] : 75; break; case 'gif': @imagecolortransparent($new_img, @imagecolorallocate($new_img, 0, 0, 0)); $src_img = @imagecreatefromgif($file_path); $write_image = 'imagegif'; $image_quality = null; break; case 'png': @imagecolortransparent($new_img, @imagecolorallocate($new_img, 0, 0, 0)); @imagealphablending($new_img, false); @imagesavealpha($new_img, true); $src_img = @imagecreatefrompng($file_path); $write_image = 'imagepng'; $image_quality = isset($options['png_quality']) ? $options['png_quality'] : 9; break; default: $src_img = null; } $success = $src_img && @imagecopyresampled( $new_img, $src_img, $dst_x, $dst_y, 0, 0, $new_width, $new_height, $img_width, $img_height ) && $write_image($new_img, $new_file_path, $image_quality); // Free up memory (imagedestroy does not delete files): @imagedestroy($src_img); @imagedestroy($new_img); return $success; } protected function get_error_message($error) { return array_key_exists($error, $this->error_messages) ? $this->error_messages[$error] : $error; } function get_config_bytes($val) { $val = trim($val); $last = strtolower($val[strlen($val) - 1]); $val = substr($val, 0, -1); switch ($last) { case 'g': $val *= 1024; case 'm': $val *= 1024; case 'k': $val *= 1024; } return $this->fix_integer_overflow($val); } protected function validate($uploaded_file, $file, $error, $index) { if ($error) { $file->error = $this->get_error_message($error); return false; } $content_length = $this->fix_integer_overflow(intval( $this->get_server_var('CONTENT_LENGTH') )); $post_max_size = $this->get_config_bytes(ini_get('post_max_size')); if ($post_max_size && ($content_length > $post_max_size)) { $file->error = $this->get_error_message('post_max_size'); return false; } if (!preg_match($this->options['accept_file_types'], $file->name)) { $file->error = $this->get_error_message('accept_file_types'); return false; } if ($uploaded_file && is_uploaded_file($uploaded_file)) { $file_size = $this->get_file_size($uploaded_file); } else { $file_size = $content_length; } if ($this->options['max_file_size'] && ( $file_size > $this->options['max_file_size'] || $file->size > $this->options['max_file_size']) ) { $file->error = $this->get_error_message('max_file_size'); return false; } if ($this->options['min_file_size'] && $file_size < $this->options['min_file_size'] ) { $file->error = $this->get_error_message('min_file_size'); return false; } if (is_int($this->options['max_number_of_files']) && ( $this->count_file_objects() >= $this->options['max_number_of_files']) ) { $file->error = $this->get_error_message('max_number_of_files'); return false; } if ($this->is_valid_image_file($uploaded_file)) { list($img_width, $img_height) = @getimagesize($uploaded_file); if (is_int($img_width)) { if ($this->options['max_width'] && $img_width > $this->options['max_width']) { $file->error = $this->get_error_message('max_width'); return false; } if ($this->options['max_height'] && $img_height > $this->options['max_height']) { $file->error = $this->get_error_message('max_height'); return false; } if ($this->options['min_width'] && $img_width < $this->options['min_width']) { $file->error = $this->get_error_message('min_width'); return false; } if ($this->options['min_height'] && $img_height < $this->options['min_height']) { $file->error = $this->get_error_message('min_height'); return false; } } } return true; } protected function upcount_name_callback($matches) { $index = isset($matches[1]) ? intval($matches[1]) + 1 : 1; $ext = isset($matches[2]) ? $matches[2] : ''; return ' (' . $index . ')' . $ext; } protected function upcount_name($name) { return preg_replace_callback( '/(?:(?: \(([\d]+)\))?(\.[^.]+))?$/', array($this, 'upcount_name_callback'), $name, 1 ); } protected function get_unique_filename($name, $type, $index, $content_range) { while (is_dir($this->get_upload_path($name))) { $name = $this->upcount_name($name); } // Keep an existing filename if this is part of a chunked upload: $uploaded_bytes = $this->fix_integer_overflow(intval($content_range[1])); while (is_file($this->get_upload_path($name))) { if ($uploaded_bytes === $this->get_file_size( $this->get_upload_path($name)) ) { break; } $name = $this->upcount_name($name); } return $name; } protected function trim_file_name($name, $type, $index, $content_range) { // Remove path information and dots around the filename, to prevent uploading // into different directories or replacing hidden system files. // Also remove control characters and spaces (\x00..\x20) around the filename: $name = trim(basename(stripslashes($name)), ".\x00..\x20"); // Use a timestamp for empty filenames: if (!$name) { $name = str_replace('.', '-', microtime(true)); } // Add missing file extension for known image types: if (strpos($name, '.') === false && preg_match('/^image\/(gif|jpe?g|png)/', $type, $matches) ) { $name .= '.' . $matches[1]; } return $name; } protected function get_file_name($name, $type, $index, $content_range) { return $this->get_unique_filename( $this->trim_file_name($name, $type, $index, $content_range), $type, $index, $content_range ); } protected function orient_image($file_path) { if (!function_exists('exif_read_data')) { return false; } $exif = @exif_read_data($file_path); if ($exif === false) { return false; } $orientation = intval(@$exif['Orientation']); if (!in_array($orientation, array(3, 6, 8))) { return false; } $image = @imagecreatefromjpeg($file_path); switch ($orientation) { case 3: $image = @imagerotate($image, 180, 0); break; case 6: $image = @imagerotate($image, 270, 0); break; case 8: $image = @imagerotate($image, 90, 0); break; default: return false; } $success = imagejpeg($image, $file_path); // Free up memory (imagedestroy does not delete files): @imagedestroy($image); return $success; } protected function handle_image_file($file_path, $file) { if ($this->options['orient_image']) { $this->orient_image($file_path); } $failed_versions = array(); foreach ($this->options['image_versions'] as $version => $options) { if ($this->create_scaled_image($file->name, $version, $options)) { if (!empty($version)) { $file->{$version . '_url'} = $this->get_download_url( $file->name, $version ); } else { $file->size = $this->get_file_size($file_path, true); } } else { $failed_versions[] = $version; } } switch (count($failed_versions)) { case 0: break; case 1: $file->error = 'Failed to create scaled version: ' . $failed_versions[0]; break; default: $file->error = 'Failed to create scaled versions: ' . implode($failed_versions, ', '); } } protected function handle_file_upload($uploaded_file, $name, $size, $type, $error, $index = null, $content_range = null) { $file = new stdClass(); $file->name = $this->get_file_name($name, $type, $index, $content_range); $file->size = $this->fix_integer_overflow(intval($size)); $file->type = $type; if ($this->validate($uploaded_file, $file, $error, $index)) { $upload_dir = $this->get_upload_path(); if (!is_dir($upload_dir)) { mkdir($upload_dir, $this->options['mkdir_mode'], true); } $file_path = $this->get_upload_path($file->name); $append_file = $content_range && is_file($file_path) && $file->size > $this->get_file_size($file_path); if ($uploaded_file && is_uploaded_file($uploaded_file)) { // multipart/formdata uploads (POST method uploads) if ($append_file) { file_put_contents( $file_path, fopen($uploaded_file, 'r'), FILE_APPEND ); } else { move_uploaded_file($uploaded_file, $file_path); } } else { // Non-multipart uploads (PUT method support) file_put_contents( $file_path, fopen('php://input', 'r'), $append_file ? FILE_APPEND : 0 ); } $file_size = $this->get_file_size($file_path, $append_file); if ($file_size === $file->size) { $file->url = $this->get_download_url($file->name); list($img_width, $img_height) = @getimagesize($file_path); if (is_int($img_width)) { $this->handle_image_file($file_path, $file); } $file->width = $img_width; $file->height = $img_height; $this->handle_form_data($file, $index); } else { $file->size = $file_size; if (!$content_range && $this->options['discard_aborted_uploads']) { unlink($file_path); $file->error = 'abort'; } } $this->set_file_delete_properties($file); } return $file; } protected function readfile($file_path) { return readfile($file_path); } protected function body($str) { echo $str; } protected function header($str) { header($str); } protected function get_server_var($id) { return isset($_SERVER[$id]) ? $_SERVER[$id] : ''; } protected function generate_response($content, $print_response = true) { if ($print_response) { $json = json_encode($content); $redirect = isset($_REQUEST['redirect']) ? stripslashes($_REQUEST['redirect']) : null; if ($redirect) { $this->header('Location: ' . sprintf($redirect, rawurlencode($json))); return; } $this->head(); if ($this->get_server_var('HTTP_CONTENT_RANGE')) { $files = isset($content[$this->options['param_name']]) ? $content[$this->options['param_name']] : null; if ($files && is_array($files) && is_object($files[0]) && $files[0]->size) { $this->header('Range: 0-' . ( $this->fix_integer_overflow(intval($files[0]->size)) - 1 )); } } $this->body($json); } return $content; } protected function get_version_param() { return isset($_GET['version']) ? basename(stripslashes($_GET['version'])) : null; } protected function get_file_name_param() { return isset($_GET['file']) ? basename(stripslashes($_GET['file'])) : null; } protected function get_file_type($file_path) { switch (strtolower(pathinfo($file_path, PATHINFO_EXTENSION))) { case 'jpeg': case 'jpg': return 'image/jpeg'; case 'png': return 'image/png'; case 'gif': return 'image/gif'; default: return ''; } } protected function download() { if (!$this->options['download_via_php']) { $this->header('HTTP/1.1 403 Forbidden'); return; } $file_name = $this->get_file_name_param(); if ($this->is_valid_file_object($file_name)) { $file_path = $this->get_upload_path($file_name, $this->get_version_param()); if (is_file($file_path)) { if (!preg_match($this->options['inline_file_types'], $file_name)) { $this->header('Content-Description: File Transfer'); $this->header('Content-Type: application/octet-stream'); $this->header('Content-Disposition: attachment; filename="' . $file_name . '"'); $this->header('Content-Transfer-Encoding: binary'); } else { // Prevent Internet Explorer from MIME-sniffing the content-type: $this->header('X-Content-Type-Options: nosniff'); $this->header('Content-Type: ' . $this->get_file_type($file_path)); $this->header('Content-Disposition: inline; filename="' . $file_name . '"'); } $this->header('Content-Length: ' . $this->get_file_size($file_path)); $this->header('Last-Modified: ' . gmdate('D, d M Y H:i:s T', filemtime($file_path))); ob_end_flush(); $this->readfile($file_path); exit; } } } protected function send_content_type_header() { $this->header('Vary: Accept'); if (strpos($this->get_server_var('HTTP_ACCEPT'), 'application/json') !== false) { $this->header('Content-type: application/json'); } else { $this->header('Content-type: text/plain'); } } protected function send_access_control_headers() { $this->header('Access-Control-Allow-Origin: ' . $this->options['access_control_allow_origin']); $this->header('Access-Control-Allow-Credentials: ' . ($this->options['access_control_allow_credentials'] ? 'true' : 'false')); $this->header('Access-Control-Allow-Methods: ' . implode(', ', $this->options['access_control_allow_methods'])); $this->header('Access-Control-Allow-Headers: ' . implode(', ', $this->options['access_control_allow_headers'])); } public function head() { $this->header('Pragma: no-cache'); $this->header('Cache-Control: no-store, no-cache, must-revalidate'); $this->header('Content-Disposition: inline; filename="files.json"'); // Prevent Internet Explorer from MIME-sniffing the content-type: $this->header('X-Content-Type-Options: nosniff'); if ($this->options['access_control_allow_origin']) { $this->send_access_control_headers(); } $this->send_content_type_header(); } public function get($print_response = true) { if ($print_response && isset($_GET['download'])) { return $this->download(); } $file_name = $this->get_file_name_param(); if ($file_name) { $response = array( substr($this->options['param_name'], 0, -1) => $this->get_file_object($file_name) ); } else { $response = array( $this->options['param_name'] => $this->get_file_objects() ); } return $this->generate_response($response, $print_response); } public function post($print_response = true) { if (isset($_REQUEST['_method']) && $_REQUEST['_method'] === 'DELETE') { return $this->delete($print_response); } $upload = isset($_FILES[$this->options['param_name']]) ? $_FILES[$this->options['param_name']] : null; // Parse the Content-Disposition header, if available: $file_name = $this->get_server_var('HTTP_CONTENT_DISPOSITION') ? rawurldecode(preg_replace( '/(^[^"]+")|("$)/', '', $this->get_server_var('HTTP_CONTENT_DISPOSITION') )) : null; // Parse the Content-Range header, which has the following form: // Content-Range: bytes 0-524287/2000000 $content_range = $this->get_server_var('HTTP_CONTENT_RANGE') ? preg_split('/[^0-9]+/', $this->get_server_var('HTTP_CONTENT_RANGE')) : null; $size = $content_range ? $content_range[3] : null; $files = array(); if ($upload && is_array($upload['tmp_name'])) { // param_name is an array identifier like "files[]", // $_FILES is a multi-dimensional array: foreach ($upload['tmp_name'] as $index => $value) { $files[] = $this->handle_file_upload( $upload['tmp_name'][$index], $file_name ? $file_name : $upload['name'][$index], $size ? $size : $upload['size'][$index], $upload['type'][$index], $upload['error'][$index], $index, $content_range ); } } else { // param_name is a single object identifier like "file", // $_FILES is a one-dimensional array: $files[] = $this->handle_file_upload( isset($upload['tmp_name']) ? $upload['tmp_name'] : null, $file_name ? $file_name : (isset($upload['name']) ? $upload['name'] : null), $size ? $size : (isset($upload['size']) ? $upload['size'] : $this->get_server_var('CONTENT_LENGTH')), isset($upload['type']) ? $upload['type'] : $this->get_server_var('CONTENT_TYPE'), isset($upload['error']) ? $upload['error'] : null, null, $content_range ); } return $this->generate_response( array($this->options['param_name'] => $files), $print_response ); } public function delete($print_response = true) { $file_name = $this->get_file_name_param(); $file_path = $this->get_upload_path($file_name); $success = is_file($file_path) && $file_name[0] !== '.' && unlink($file_path); if ($success) { foreach ($this->options['image_versions'] as $version => $options) { if (!empty($version)) { $file = $this->get_upload_path($file_name, $version); if (is_file($file)) { unlink($file); } } } } return $this->generate_response(array('success' => $success), $print_response); } protected function is_valid_image_file($file_path) { return (preg_match('/\.(gif|jpe?g|png)$/i', $file_path)); } } PK ӠqY^NQ Q AccessibleMonologWriter.phpnu [ resource; } public function addHandler($handler) { if (!$this->resource) $this->settings['handlers'][] = $handler; else $this->getWriter()->pushHandler($handler); } public function addProcessor($processor) { if (!$this->resource) $this->settings['processors'][] = $processor; else $this->getWriter()->pushProcessor($processor); } }PK ӠqY$3 McaasGrant.phpnu [ client = $this->server->getClientStorage()->get( $clientId, $clientSecret, null, $this->getIdentifier() ); if (($this->client instanceof ClientEntity) === false) { throw new InvalidClientException(); } return $this; } /** * Complete the client credentials grant * * @return string * * @throws */ public function completeFlow() { // Validate any scopes that are in the request (should always return default) $scopes = $this->validateScopes('', $this->client); // Create a new session $session = new SessionEntity($this->server); $session->setOwner('client', $this->client->getId()); $session->associateClient($this->client); // Generate an access token $accessToken = new AccessTokenEntity($this->server); $accessToken->setId(SecureKey::generate()); $accessToken->setExpireTime($this->getAccessTokenTTL() + time()); // Associate scopes with the session and access token foreach ($scopes as $scope) { $session->associateScope($scope); } foreach ($session->getScopes() as $scope) { $accessToken->associateScope($scope); } // Save everything $session->save(); $accessToken->setSession($session); $accessToken->save(); return $accessToken->getId(); } }PK ӠqYʭ6 AttachmentUploadHandler.phpnu [ options['controller']; /* @var \Xibo\Controller\Notification $controller */ $controller->getLog()->debug('Upload complete for name: ' . $file->name); } }PK ӠqY/1H 1H XiboUploadHandler.phpnu [ options['controller']; /* @var \Xibo\Controller\Library $controller */ // Handle form data, e.g. $_REQUEST['description'][$index] // Link the file to the module $fileName = $file->name; $filePath = $controller->getConfig()->getSetting('LIBRARY_LOCATION') . 'temp/' . $fileName; $controller->getLog()->debug('Upload complete for name: ' . $fileName . '. Index is %s.', $index); // Upload and Save try { // Check Library if ($this->options['libraryQuotaFull']) throw new LibraryFullException(sprintf(__('Your library is full. Library Limit: %s K'), $this->options['libraryLimit'])); // Check for a user quota // this method has the ability to reconnect to MySQL in the event that the upload has taken a long time. // OSX-381 $controller->getUser()->isQuotaFullByUser(true); // Get some parameters if ($index === null) { if (isset($_REQUEST['name'])) { $name = $_REQUEST['name']; } else { $name = $fileName; } if (isset($_REQUEST['tags'])) { $tags = $_REQUEST['tags']; } else { $tags = ''; } } else { if (isset($_REQUEST['name'][$index])) { $name = $_REQUEST['name'][$index]; } else { $name = $fileName; } if (isset($_REQUEST['tags'][$index])) { $tags = $_REQUEST['tags'][$index]; } else { $tags = ''; } } // Guess the type $module = $controller->getModuleFactory()->getByExtension(strtolower(substr(strrchr($fileName, '.'), 1))); $module = $controller->getModuleFactory()->create($module->type); $controller->getLog()->debug('Module Type = %s, Name = %s', $module->getModuleType(), $module->getModuleName()); // Do we need to run any pre-processing on the file? $module->preProcessFile($filePath); // Old Media Id or not? if ($this->options['oldMediaId'] != 0) { $updateInLayouts = ($this->options['updateInLayouts'] == 1); $deleteOldRevisions = ($this->options['deleteOldRevisions'] == 1); $controller->getLog()->debug('Replacing old with new - updateInLayouts = %d, deleteOldRevisions = %d', $updateInLayouts, $deleteOldRevisions); // Load old media $oldMedia = $controller->getMediaFactory()->getById($this->options['oldMediaId']); // Check permissions if (!$controller->getUser()->checkEditable($oldMedia)) throw new AccessDeniedException(__('Access denied replacing old media')); // Check to see if we are changing the media type if ($oldMedia->mediaType != $module->getModuleType() && $this->options['allowMediaTypeChange'] == 0) throw new \InvalidArgumentException(__('You cannot replace this media with an item of a different type')); // Set the old record to edited $oldMedia->isEdited = 1; $oldMedia->save(['validate' => false]); // The media name might be empty here, because the user isn't forced to select it $name = ($name == '') ? $oldMedia->name : $name; $tags = ($tags == '') ? '' : $tags; // Add the Media // the userId is either the existing user (if we are changing media type) or the currently logged in user otherwise. $media = $controller->getMediaFactory()->create( $name, $fileName, $module->getModuleType(), (($this->options['allowMediaTypeChange'] == 1) ? $oldMedia->getOwnerId() : $this->options['userId']) ); if ($tags != '') { $concatTags = (string)$oldMedia->tags . ',' . $tags; $media->replaceTags($controller->getTagFactory()->tagsFromString($concatTags)); } // Set the duration if ($oldMedia->mediaType != 'video' && $media->mediaType != 'video') $media->duration = $oldMedia->duration; else $media->duration = $module->determineDuration($filePath); // Pre-process $module->preProcess($media, $filePath); // Raise an event for this media item $controller->getDispatcher()->dispatch(LibraryReplaceEvent::$NAME, new LibraryReplaceEvent($module, $media, $oldMedia)); $media->enableStat = $oldMedia->enableStat; $media->expires = $this->options['expires']; // Save $media->save(['oldMedia' => $oldMedia]); // Post process $module->postProcess($media); $controller->getLog()->debug('Copying permissions to new media'); foreach ($controller->getPermissionFactory()->getAllByObjectId($controller->getUser(), get_class($oldMedia), $oldMedia->mediaId) as $permission) { /* @var Permission $permission */ $permission = clone $permission; $permission->objectId = $media->mediaId; $permission->save(); } // Do we want to replace this in all layouts? if ($updateInLayouts) { $controller->getLog()->debug('Replace in all Layouts selected. Getting associated widgets'); foreach ($controller->getWidgetFactory()->getByMediaId($oldMedia->mediaId) as $widget) { /* @var Widget $widget */ if (!$controller->getUser()->checkEditable($widget)) { // Widget that we cannot update, this means we can't delete the original mediaId when it comes time to do so. $deleteOldRevisions = false; $controller->getLog()->info('Media used on Widget that we cannot edit. Delete Old Revisions has been disabled.'); } // If we are replacing an audio media item, we should check to see if the widget we've found has any // audio items assigned. if ($module->getModuleType() == 'audio' && in_array($oldMedia->mediaId, $widget->getAudioIds())) { $controller->getLog()->debug('Found audio on widget that needs updating. widgetId = ' . $widget->getId() . '. Linking ' . $media->mediaId); $widget->unassignAudioById($oldMedia->mediaId); $widget->assignAudioById($media->mediaId); $widget->save(); } else if (count($widget->getPrimaryMedia()) > 0 && $widget->getPrimaryMediaId() == $oldMedia->mediaId) { // We're only interested in primary media at this point (no audio) // Check whether this widget is of the same type as our incoming media item if ($widget->type != $module->getModuleType()) { // Are we supposed to switch, or should we prevent? if ($this->options['allowMediaTypeChange'] == 1) { $widget->type = $module->getModuleType(); } else { throw new \InvalidArgumentException(__('You cannot replace this media with an item of a different type')); } } $controller->getLog()->debug('Found widget that needs updating. ID = %d. Linking %d', $widget->getId(), $media->mediaId); $widget->unassignMedia($oldMedia->mediaId); $widget->assignMedia($media->mediaId); // calculate duration $module->setWidget($widget); $widget->calculateDuration($module); // Raise an event for this media item $controller->getDispatcher()->dispatch(LibraryReplaceWidgetEvent::$NAME, new LibraryReplaceWidgetEvent($module, $widget, $media, $oldMedia)); // Save $widget->save(['alwaysUpdate' => true]); } } // Update any background images if ($media->mediaType == 'image') { $controller->getLog()->debug('Updating layouts with the old media %d as the background image.', $oldMedia->mediaId); // Get all Layouts with this as the background image foreach ($controller->getLayoutFactory()->query(null, ['disableUserCheck' => 1, 'backgroundImageId' => $oldMedia->mediaId]) as $layout) { /* @var Layout $layout */ if (!$controller->getUser()->checkEditable($layout)) { // Widget that we cannot update, this means we can't delete the original mediaId when it comes time to do so. $deleteOldRevisions = false; $controller->getLog()->info('Media used on Widget that we cannot edit. Delete Old Revisions has been disabled.'); } $controller->getLog()->debug('Found layout that needs updating. ID = %d. Setting background image id to %d', $layout->layoutId, $media->mediaId); $layout->backgroundImageId = $media->mediaId; $layout->save(); } } } else if ($this->options['widgetId'] != 0) { $controller->getLog()->debug('Swapping a specific widget only.'); // swap this one $widget = $controller->getWidgetFactory()->getById($this->options['widgetId']); if (!$controller->getUser()->checkEditable($widget)) throw new AccessDeniedException(); $widget->unassignMedia($oldMedia->mediaId); $widget->assignMedia($media->mediaId); $widget->save(); } // We either want to Link the old record to this one, or delete it if ($updateInLayouts && $deleteOldRevisions) { $controller->getLog()->debug('Delete old revisions of ' . $oldMedia->mediaId); // Check we have permission to delete this media if (!$controller->getUser()->checkDeleteable($oldMedia)) throw new AccessDeniedException(); try { // Join the prior revision up with the new media. $priorMedia = $controller->getMediaFactory()->getParentById($oldMedia->mediaId); $controller->getLog()->debug('Prior media found, joining ' . $priorMedia->mediaId . ' with ' . $media->mediaId); $priorMedia->parentId = $media->mediaId; $priorMedia->save(['validate' => false]); } catch (NotFoundException $e) { // Nothing to do then $controller->getLog()->debug('No prior media found'); } $oldMedia->setChildObjectDependencies($controller->getLayoutFactory(), $controller->getWidgetFactory(), $controller->getDisplayGroupFactory(), $controller->getDisplayFactory(), $controller->getScheduleFactory(), $controller->getPlayerVersionFactory()); $oldMedia->delete(); } else { $oldMedia->parentId = $media->mediaId; $oldMedia->save(['validate' => false]); } } else { // The media name might be empty here, because the user isn't forced to select it $name = ($name == '') ? $fileName : $name; $tags = ($tags == '') ? '' : $tags; // Add the Media $media = $controller->getMediaFactory()->create($name, $fileName, $module->getModuleType(), $this->options['userId']); if ($tags != '') { $media->replaceTags($controller->getTagFactory()->tagsFromString($tags)); } // Set the duration $media->duration = $module->determineDuration($filePath); // Pre-process $module->preProcess($media, $filePath); if ($media->enableStat == null) { $media->enableStat = $controller->getConfig()->getSetting('MEDIA_STATS_ENABLED_DEFAULT'); } $media->expires = $this->options['expires']; // Save $media->save(); // Post process $module->postProcess($media); // Permissions foreach ($controller->getPermissionFactory()->createForNewEntity($controller->getUser(), get_class($media), $media->getId(), $controller->getConfig()->getSetting('MEDIA_DEFAULT'), $controller->getUserGroupFactory()) as $permission) { /* @var Permission $permission */ $permission->save(); } } // Configure the return values according to the media item we've added $file->name = $name; $file->mediaId = $media->mediaId; $file->storedas = $media->storedAs; $file->duration = $media->duration; $file->retired = $media->retired; $file->fileSize = $media->fileSize; $file->md5 = $media->md5; $file->enableStat = $media->enableStat; $file->mediaType = $module->getModuleType(); // Test to ensure the final file size is the same as the file size we're expecting if ($file->fileSize != $file->size) throw new InvalidArgumentException(__('Sorry this is a corrupted upload, the file size doesn\'t match what we\'re expecting.'), 'size'); // Fonts, then install if ($module->getModuleType() == 'font') { $controller->installFonts(); } // Are we assigning to a Playlist? if ($this->options['playlistId'] != 0 && $this->options['widgetId'] == 0) { $controller->getLog()->debug('Assigning uploaded media to playlistId ' . $this->options['playlistId']); // Get the Playlist $playlist = $controller->getPlaylistFactory()->getById($this->options['playlistId']); // Create a Widget and add it to our region $widget = $controller->getWidgetFactory()->create($this->options['userId'], $playlist->playlistId, $module->getModuleType(), $media->duration); // Assign the widget to the module $module->setWidget($widget); // Set default options (this sets options on the widget) $module->setDefaultWidgetOptions(); // Assign media $widget->assignMedia($media->mediaId); // Calculate the widget duration for new uploaded media widgets $widget->calculateDuration($module); // Assign the new widget to the playlist $playlist->assignWidget($widget, $this->options['displayOrder'] ?? null); // Save the playlist $playlist->save(); // Configure widgetId is reponse $file->widgetId = $widget->widgetId; // Handle permissions // https://github.com/xibosignage/xibo/issues/1274 if ($controller->getConfig()->getSetting('INHERIT_PARENT_PERMISSIONS') == 1) { // Apply permissions from the Parent foreach ($playlist->permissions as $permission) { /* @var Permission $permission */ $permission = $controller->getPermissionFactory()->create($permission->groupId, get_class($widget), $widget->getId(), $permission->view, $permission->edit, $permission->delete); $permission->save(); } } else { foreach ($controller->getPermissionFactory()->createForNewEntity($controller->getUser(), get_class($widget), $widget->getId(), $controller->getConfig()->getSetting('LAYOUT_DEFAULT'), $controller->getUserGroupFactory()) as $permission) { /* @var Permission $permission */ $permission->save(); } } } } catch (Exception $e) { $controller->getLog()->error('Error uploading media: %s', $e->getMessage()); $controller->getLog()->debug($e->getTraceAsString()); // Unlink the temporary file @unlink($filePath); $file->error = $e->getMessage(); $controller->getApp()->commit = false; } } } PK ӠqYr DataSetUploadHandler.phpnu [ options['controller']; /* @var \Xibo\Controller\DataSet $controller */ // Handle form data, e.g. $_REQUEST['description'][$index] $fileName = $file->name; $controller->getLog()->debug('Upload complete for ' . $fileName . '.'); // Upload and Save try { // Authenticate $controller = $this->options['controller']; $dataSet = $controller->getDataSetFactory()->getById($this->options['dataSetId']); if (!$controller->getUser()->checkEditable($dataSet)) throw new AccessDeniedException(); // We are allowed to edit - pull all required parameters from the request object $overwrite = $controller->getSanitizer()->getCheckbox('overwrite'); $ignoreFirstRow = $controller->getSanitizer()->getCheckbox('ignorefirstrow'); $controller->getLog()->debug('Options provided - overwrite = %d, ignore first row = %d', $overwrite, $ignoreFirstRow); // Enumerate over the columns in the DataSet and set a row value for each $spreadSheetMapping = []; foreach ($dataSet->getColumn() as $column) { /* @var \Xibo\Entity\DataSetColumn $column */ if ($column->dataSetColumnTypeId == 1) { // Has this column been provided in the mappings? $spreadSheetColumn = 0; if (isset($_REQUEST['csvImport_' . $column->dataSetColumnId])) $spreadSheetColumn = (($index === null) ? $_REQUEST['csvImport_' . $column->dataSetColumnId] : $_REQUEST['csvImport_' . $column->dataSetColumnId][$index]); // If it has been left blank, then skip if ($spreadSheetColumn != 0) $spreadSheetMapping[($spreadSheetColumn - 1)] = $column->heading; } } // Delete the data? if ($overwrite == 1) $dataSet->deleteData(); // Load the file ini_set('auto_detect_line_endings', true); $firstRow = true; $i = 0; $handle = fopen($controller->getConfig()->getSetting('LIBRARY_LOCATION') . 'temp/' . $fileName, 'r'); while (($data = fgetcsv($handle)) !== FALSE ) { $i++; $row = []; // The CSV file might have headings, so ignore the first row. if ($firstRow) { $firstRow = false; if ($ignoreFirstRow == 1) continue; } for ($cell = 0; $cell < count($data); $cell++) { // Insert the data into the correct column if (isset($spreadSheetMapping[$cell])) { // Sanitize the data a bit $item = $data[$cell]; if ($item == '') $item = null; $row[$spreadSheetMapping[$cell]] = $item; } } try { $dataSet->addRow($row); } catch (\PDOException $PDOException) { $controller->getLog()->error('Error importing row ' . $i . '. E = ' . $PDOException->getMessage()); $controller->getLog()->debug($PDOException->getTraceAsString()); throw new InvalidArgumentException(__('Unable to import row %d', $i), 'row'); } } // Close the file fclose($handle); // Change the auto detect setting back ini_set('auto_detect_line_endings', false); // TODO: update list content definitions // Save the dataSet $dataSet->lastDataEdit = time(); $dataSet->save(['validate' => false, 'saveColumns' => false]); // Tidy up the temporary file @unlink($controller->getConfig()->getSetting('LIBRARY_LOCATION') . 'temp/' . $fileName); } catch (Exception $e) { $file->error = $e->getMessage(); } } }PK ӠqY: NullSession.phpnu [ options['controller']; /* @var \Xibo\Controller\Layout $controller */ // Handle form data, e.g. $_REQUEST['description'][$index] $fileName = $file->name; $controller->getLog()->debug('Upload complete for ' . $fileName . '.'); // Upload and Save try { // Check Library if ($this->options['libraryQuotaFull']) throw new LibraryFullException(sprintf(__('Your library is full. Library Limit: %s K'), $this->options['libraryLimit'])); // Check for a user quota $controller->getUser()->isQuotaFullByUser(); // Parse parameters $name = isset($_REQUEST['name']) ? $_REQUEST['name'][$index] : ''; $template = isset($_REQUEST['template']) ? $_REQUEST['template'][$index] : 0; $replaceExisting = isset($_REQUEST['replaceExisting']) ? $_REQUEST['replaceExisting'][$index] : 0; $importTags = isset($_REQUEST['importTags']) ? $_REQUEST['importTags'][$index] : 0; $useExistingDataSets = isset($_REQUEST['useExistingDataSets']) ? $_REQUEST['useExistingDataSets'][$index] : 0; $importDataSetData = isset($_REQUEST['importDataSetData']) ? $_REQUEST['importDataSetData'][$index] : 0; /* @var Layout $layout */ $layout = $controller->getLayoutFactory()->createFromZip( $controller->getConfig()->getSetting('LIBRARY_LOCATION') . 'temp/' . $fileName, $name, $this->options['userId'], $template, $replaceExisting, $importTags, $useExistingDataSets, $importDataSetData, $this->options['libraryController'] ); $layout->save(); $layout->managePlaylistClosureTable($layout); @unlink($controller->getConfig()->getSetting('LIBRARY_LOCATION') . 'temp/' . $fileName); // Set the name for the return $file->name = $layout->layout; $file->id = $layout->layoutId; } catch (Exception $e) { $controller->getLog()->error('Error importing Layout: %s', $e->getMessage()); $controller->getLog()->debug($e->getTraceAsString()); $file->error = $e->getMessage(); $controller->getApp()->commit = false; } } }PK ӠqYF$kK kK Install.phpnu [ PK ӠqY߆D D K Environment.phpnu [ PK ӠqYɩ )i ByteFormatter.phpnu [ PK ӠqY p BackupUploadHandler.phpnu [ PK ӠqY(a Zp HttpsDetect.phpnu [ PK ӠqYE3 E3 w Session.phpnu [ PK ӠqYi^ ^ , Random.phpnu [ PK ӠqYVH Į ObjectVars.phpnu [ PK ӠqYn DatabaseLogHandler.phpnu [ PK ӠqYY ܼ Translate.phpnu [ PK ӠqYU ApplicationState.phpnu [ PK ӠqY- @ Pbkdf2Hash.phpnu [ PK ӠqY/2xA ) QuickChartQRProvider.phpnu [ PK ӠqYU* * WakeOnLan.phpnu [ PK ӠqY7Tb b Y. LogProcessor.phpnu [ PK ӠqYBQ Q 3 BlueImpUploadHandler.phpnu [ PK ӠqY^NQ Q AccessibleMonologWriter.phpnu [ PK ӠqY$3 0 McaasGrant.phpnu [ PK ӠqYʭ6 G AttachmentUploadHandler.phpnu [ PK ӠqY/1H 1H p XiboUploadHandler.phpnu [ PK ӠqYr DataSetUploadHandler.phpnu [ PK ӠqY: .# NullSession.phpnu [ PK ӠqY55 ( LayoutUploadHandler.phpnu [ PK ] N3