setTimezone(get('timezone')); $config->setClientTimeout(HTTP_TIMEOUT); $config->setClientUserAgent(HTTP_USER_AGENT); $config->setGrabberUserAgent(HTTP_USER_AGENT); $config->setProxyHostname(PROXY_HOSTNAME); $config->setProxyPort(PROXY_PORT); $config->setProxyUsername(PROXY_USERNAME); $config->setProxyPassword(PROXY_PASSWORD); $config->setFilterIframeWhitelist(get_iframe_whitelist()); return $config; } function get_iframe_whitelist() { return array( '//www.youtube.com', 'http://www.youtube.com', 'https://www.youtube.com', 'http://player.vimeo.com', 'https://player.vimeo.com', 'http://www.dailymotion.com', 'https://www.dailymotion.com', ); } // Send a debug message to the console function debug($line) { Logging::setMessage($line); write_debug(); } // Write PicoFeed debug output to a file function write_debug() { if (DEBUG) { file_put_contents(DEBUG_FILENAME, implode(PHP_EOL, Logging::getMessages())); } } // Get available timezone function get_timezones() { $timezones = \timezone_identifiers_list(); return array_combine(array_values($timezones), $timezones); } // Get all supported languages function get_languages() { $languages = array( 'cs_CZ' => t('Czech'), 'de_DE' => t('German'), 'en_US' => t('English'), 'es_ES' => t('Spanish'), 'fr_FR' => t('French'), 'it_IT' => t('Italian'), 'pt_BR' => t('Portuguese'), 'zh_CN' => t('Simplified Chinese'), ); asort($languages); return $languages; } // Get all skins function get_themes() { $themes = array( 'original' => t('Original') ); if (file_exists(THEME_DIRECTORY)) { $dir = new \DirectoryIterator(THEME_DIRECTORY); foreach ($dir as $fileinfo) { if (! $fileinfo->isDot() && $fileinfo->isDir()) { $themes[$dir->getFilename()] = ucfirst($dir->getFilename()); } } } return $themes; } // Sorting direction choices for items function get_sorting_directions() { return array( 'asc' => t('Older items first'), 'desc' => t('Most recent first'), ); } // Autoflush choices for items function get_autoflush_options() { return array( '0' => t('Never'), '-1' => t('Immediately'), '1' => t('After %d day', 1), '5' => t('After %d days', 5), '15' => t('After %d days', 15), '30' => t('After %d days', 30) ); } // Number of items per pages function get_paging_options() { return array( 50 => 50, 100 => 100, 150 => 150, 200 => 200, 250 => 250, ); } // Get redirect options when there is nothing to read function get_nothing_to_read_redirections() { return array( 'feeds' => t('Subscription page'), 'history' => t('History page'), 'bookmarks' => t('Bookmark page'), ); } // Generate a token from /dev/urandom or with uniqid() if open_basedir is enabled function generate_token() { if (function_exists('openssl_random_pseudo_bytes')) { return bin2hex(\openssl_random_pseudo_bytes(16)); } else if (ini_get('open_basedir') === '' && strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN') { return hash('sha256', file_get_contents('/dev/urandom', false, null, 0, 30)); } return hash('sha256', uniqid(mt_rand(), true)); } // Regenerate tokens for the API and bookmark feed function new_tokens() { $values = array( 'api_token' => generate_token(), 'feed_token' => generate_token(), ); return Database::get('db')->table('config')->update($values); } // Save tokens for external authentication function save_auth_token($type, $value) { return Database::get('db') ->table('config') ->update(array( 'auth_'.$type.'_token' => $value )); } // Clear authentication tokens function remove_auth_token($type) { Database::get('db') ->table('config') ->update(array( 'auth_'.$type.'_token' => '' )); $_SESSION['config'] = get_all(); } // Get a config value from the DB or from the session function get($name) { if (! isset($_SESSION)) { return Database::get('db')->table('config')->findOneColumn($name); } else { if (! isset($_SESSION['config'][$name])) { $_SESSION['config'] = get_all(); } if (isset($_SESSION['config'][$name])) { return $_SESSION['config'][$name]; } } return null; } // Get all config parameters function get_all() { return Database::get('db') ->table('config') ->columns( 'username', 'language', 'timezone', 'autoflush', 'nocontent', 'items_per_page', 'theme', 'api_token', 'feed_token', 'auth_google_token', 'auth_mozilla_token', 'items_sorting_direction', 'redirect_nothing_to_read', 'auto_update_url' ) ->findOne(); } // Validation for edit action function validate_modification(array $values) { $rules = array( new Validators\Required('username', t('The user name is required')), new Validators\MaxLength('username', t('The maximum length is 50 characters'), 50), new Validators\Required('autoflush', t('Value required')), new Validators\Required('items_per_page', t('Value required')), new Validators\Integer('items_per_page', t('Must be an integer')), new Validators\Required('theme', t('Value required')), ); if (ENABLE_AUTO_UPDATE) { $rules[] = new Validators\Required('auto_update_url', t('Value required')); } if (! empty($values['password'])) { $rules[] = new Validators\Required('password', t('The password is required')); $rules[] = new Validators\MinLength('password', t('The minimum length is 6 characters'), 6); $rules[] = new Validators\Required('confirmation', t('The confirmation is required')); $rules[] = new Validators\Equals('password', 'confirmation', t('Passwords doesn\'t match')); } $v = new Validator($values, $rules); return array( $v->execute(), $v->getErrors() ); } // Save config into the database and update the session function save(array $values) { // Update the password if needed if (! empty($values['password'])) { $values['password'] = \password_hash($values['password'], PASSWORD_BCRYPT); } else { unset($values['password']); } unset($values['confirmation']); // Reload configuration in session $_SESSION['config'] = $values; // Reload translations for flash session message \Translator\load($values['language']); // If the user does not want content of feeds, remove it in previous ones if (isset($values['nocontent']) && (bool) $values['nocontent']) { Database::get('db')->table('items')->update(array('content' => '')); } return Database::get('db')->table('config')->update($values); }