From e3de9d7dd1331f9718e04cc98e9ca7cfa27cf4aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20L=C3=A9cureuil?= Date: Sun, 17 May 2020 14:46:00 +0200 Subject: Sync with master of moonmoon ( version 9.0.0-rc) Source from https://github.com/Emmafrs/moonmoon/ --- common/CONTRIBUTING.md | 37 + common/LICENSE | 1 + common/README.md | 66 ++ common/VERSION | 2 +- common/admin/administration.php | 11 +- common/admin/changepassword.php | 8 +- common/admin/inc/auth.inc.php | 16 +- common/admin/index.php | 15 +- common/admin/login.php | 7 +- common/admin/logout.php | 9 +- common/admin/purgecache.php | 14 +- common/admin/subscriptions.php | 30 +- common/app/app.php | 37 +- common/app/classes/CSRF.php | 55 + common/app/classes/Cache.php | 254 +++++ common/app/classes/Opml.php | 70 ++ common/app/classes/OpmlManager.php | 50 + common/app/classes/Planet.php | 266 +++++ common/app/classes/PlanetConfig.php | 166 ++- common/app/classes/PlanetError.php | 23 +- common/app/classes/PlanetFeed.php | 20 +- common/app/classes/PlanetItem.php | 11 +- common/app/classes/Simplel10n.php | 52 + common/app/helpers.php | 130 +++ common/app/l10n/de.lang | 219 ++++ common/app/l10n/en.lang | 4 + common/app/l10n/es.lang | 244 ++++ common/app/l10n/extract.php | 13 +- common/app/l10n/fr.lang | 4 + common/atom.php | 8 +- common/bin/build_release.sh | 20 + common/composer.json | 35 + common/composer.lock | 1599 +++++++++++++++++++++++++++ common/cron.php | 10 +- common/custom/img/moonmoon.png | Bin 0 -> 73408 bytes common/custom/img/moonmoon@128w.png | Bin 0 -> 8671 bytes common/custom/img/moonmoon@256w.png | Bin 0 -> 24255 bytes common/custom/style/default.css | 136 ++- common/custom/views/archive/footer.tpl.php | 2 +- common/custom/views/archive/index.tpl.php | 8 +- common/custom/views/archive/sidebar.tpl.php | 2 +- common/custom/views/default/footer.tpl.php | 2 +- common/custom/views/default/index.tpl.php | 12 +- common/custom/views/default/sidebar.tpl.php | 2 +- common/custom/views/default/top.tpl.php | 2 +- common/custom/views/install.tpl.php | 119 ++ common/index.php | 22 +- common/install.php | 170 +-- common/phpunit.xml | 20 + common/postload.php | 40 +- common/tests/GuzzleHarness.php | 20 + common/tests/HelpersTest.php | 15 + common/tests/InstallTest.php | 61 + common/tests/PlanetConfigTest.php | 73 ++ common/tests/PlanetErrorTest.php | 12 + common/tests/PlanetTest.php | 84 ++ 56 files changed, 3953 insertions(+), 355 deletions(-) create mode 100644 common/CONTRIBUTING.md create mode 100644 common/README.md create mode 100644 common/app/classes/CSRF.php create mode 100644 common/app/classes/Cache.php create mode 100644 common/app/classes/Opml.php create mode 100644 common/app/classes/OpmlManager.php create mode 100644 common/app/classes/Planet.php create mode 100755 common/app/classes/Simplel10n.php create mode 100644 common/app/helpers.php create mode 100644 common/app/l10n/de.lang create mode 100644 common/app/l10n/es.lang create mode 100755 common/bin/build_release.sh create mode 100644 common/composer.json create mode 100644 common/composer.lock create mode 100644 common/custom/img/moonmoon.png create mode 100644 common/custom/img/moonmoon@128w.png create mode 100644 common/custom/img/moonmoon@256w.png create mode 100644 common/custom/views/install.tpl.php create mode 100644 common/phpunit.xml create mode 100644 common/tests/GuzzleHarness.php create mode 100644 common/tests/HelpersTest.php create mode 100644 common/tests/InstallTest.php create mode 100644 common/tests/PlanetConfigTest.php create mode 100644 common/tests/PlanetErrorTest.php create mode 100644 common/tests/PlanetTest.php diff --git a/common/CONTRIBUTING.md b/common/CONTRIBUTING.md new file mode 100644 index 0000000..1402a0c --- /dev/null +++ b/common/CONTRIBUTING.md @@ -0,0 +1,37 @@ +# Contributing + +First of all, thanks a lot for considering to contribute! + +## Found a bug? + +* Nice catch! +* Make sure that this bug is not already present in our + [Issues](https://github.com/moonmoon/moonmoon/issues) tracker. +* If none matches, please + [create a new ticket](https://github.com/moonmoon/moonmoon/issues/new). + +## Fixing a bug with a patch you made? + +* Awesome! +* If the bug you are fixing is present in our + [Issues tracker](https://github.com/moonmoon/moonmoon/issues), don't + forget to mention the related issue. +* Make sure to stick to the [PSR-2](http://www.php-fig.org/psr/psr-2/) + coding style. + +## Adding a new feature? + +* Marvelous! +* If it's not too late, please create a new ticket in the + [Issues tracker](https://github.com/moonmoon/moonmoon/issues/new) before + developing something. Maybe it does not really fit into moonmoon and + we may not merge it :( +* Make sure to stick to the [PSR-2](http://www.php-fig.org/psr/psr-2/) + coding style. + +## Seeking support ? + +* Is your problem already listed in our [FAQ](https://github.com/moonmoon/moonmoon/wiki/Faq)? +* If not, please create a ticket in our + [Issues tracker](https://github.com/moonmoon/moonmoon/issues/new). +* You more details you give (version, steps to reproduce…), the better we'll help you :-) diff --git a/common/LICENSE b/common/LICENSE index 8d83edd..bb0603a 100644 --- a/common/LICENSE +++ b/common/LICENSE @@ -30,3 +30,4 @@ Contributors: François Granger Pep, http://www.callmepep.org/ Pascal Chevrel +Javier Guerra diff --git a/common/README.md b/common/README.md new file mode 100644 index 0000000..0fcfda0 --- /dev/null +++ b/common/README.md @@ -0,0 +1,66 @@ +

+ +

+ + +moonmoon [![Build Status](https://travis-ci.org/moonmoon/moonmoon.svg?branch=master)](https://travis-ci.org/moonmoon/moonmoon) +======== + +Moonmoon is a web based aggregator similar to planetplanet. +It can be used to blend articles from different blogs with same interests into a single page. + +Moonmoon is simple: it only aggregates feeds and spits them out in one single page. +It does not archive articles, it does not do comments nor votes. + +Requirements +------------ +You will need a web hosting with at least PHP 5.6 (PHP 7 is also supported). + +If you are installing moonmoon on a Linux private server (VPS, dedicated host), +please note that you will need to install the package `php-xml`. + +Installing +---------- + +Installation steps (shared hosting or virtual / dedicated server) can be found +[in the wiki](https://github.com/moonmoon/moonmoon/wiki/How-to-install). + +Docker images are also available in [moonmoon/docker-images](https://github.com/moonmoon/docker-images). +Theses images are probably not production-ready but should work for manual testing. + +Contributing +------------ + +You want to contribute to moonmoon? Perfect! [We wrote some guidelines to help you +craft the best Issue / Pull Request possible](https://github.com/moonmoon/moonmoon/blob/master/CONTRIBUTING.md), +don't hesitate to take a look at it :-) + +License +------- + +Moonmoon is free software and is released under the [BSD license](https://github.com/moonmoon/moonmoon/blob/master/LICENSE). +Third-party code differently licensed is included in this project, in which case mention is always made of +the applicable license. + +[The logo](https://github.com/moonmoon/moonmoon/raw/master/custom/img/moonmoon.png) was designed by [@rakujira](https://twitter.com/rakujira). + +Configuration options +--------------------- +After installation, configuration is kept in a YAML formatted `custom/config.yml`: + +```%yaml +url: http://planet.example.net # your planet base URL +name: My Planet # your planet front page name +locale: en # front page locale +items: 10 # how many items to show +refresh: 240 # feeds cache timeout (in seconds) +cache: 10 # front page cache timeout (in seconds) +cachedir: ./cache # where is cache stored +postmaxlength: 0 # deprecated +shuffle: 0 # deprecated +nohtml: 0 # deprecated +categories: # only list posts that have one + # of these (tag or category) +debug: false # debug mode (dangerous in production!) +checkcerts: true # check feeds certificates +``` diff --git a/common/VERSION b/common/VERSION index 38f8e88..2a8cbc6 100644 --- a/common/VERSION +++ b/common/VERSION @@ -1 +1 @@ -dev +9.0.0-rc diff --git a/common/admin/administration.php b/common/admin/administration.php index 1202e91..26f6710 100755 --- a/common/admin/administration.php +++ b/common/admin/administration.php @@ -1,9 +1,10 @@ getPeople(); $page_id = 'admin-admin'; $header_extra = <<<"HTML" @@ -23,6 +24,7 @@ $page_content = <<<"FRAGMENT"

{$l10n->getString('Clear cache')}

+

{$l10n->getString('Clearing the cache will make moonmoon reload all feeds.')}

@@ -31,6 +33,7 @@ $page_content = <<<"FRAGMENT"

{$l10n->getString('Change administrator password')}

+

@@ -39,4 +42,4 @@ FRAGMENT; $footer_extra = ''; $admin_access = 1; -require_once dirname(__FILE__) . '/template.php'; +require_once __DIR__ . '/template.php'; diff --git a/common/admin/changepassword.php b/common/admin/changepassword.php index 1fa505e..3b4500e 100644 --- a/common/admin/changepassword.php +++ b/common/admin/changepassword.php @@ -1,9 +1,11 @@ verify($_POST['_csrf'], 'frmPassword') && isset($_POST['password']) && ('' != $_POST['password'])) { $out = ''; - file_put_contents(dirname(__FILE__).'/inc/pwd.inc.php', $out); + file_put_contents(__DIR__.'/inc/pwd.inc.php', $out); die("Password changed. Login"); } else { die('Can not change password'); diff --git a/common/admin/inc/auth.inc.php b/common/admin/inc/auth.inc.php index d21467b..0acf934 100644 --- a/common/admin/inc/auth.inc.php +++ b/common/admin/inc/auth.inc.php @@ -1,11 +1,13 @@ \ No newline at end of file diff --git a/common/admin/index.php b/common/admin/index.php index 28f7198..0118923 100755 --- a/common/admin/index.php +++ b/common/admin/index.php @@ -1,10 +1,10 @@ loadOpml(dirname(__FILE__) . '/../custom/people.opml')) { +if (0 < $Planet->loadOpml(__DIR__ . '/../custom/people.opml')) { $Planet->loadFeeds(); $items = $Planet->getItems(); } @@ -79,6 +79,7 @@ ob_start();

+
@@ -87,6 +88,7 @@ ob_start();

+

@@ -99,6 +101,7 @@ ob_start(); + @@ -118,10 +121,12 @@ ob_start(); } else { echo _g('Not in cache'); } + $check_is_down = $opml_person->getIsDown() === '1' ? 'checked="checked"' : ''; ?> + value="1" /> @@ -133,4 +138,4 @@ $page_content = ob_get_contents(); ob_end_clean(); $admin_access = 1; -require_once dirname(__FILE__) . '/template.php'; +require_once __DIR__ . '/template.php'; diff --git a/common/admin/login.php b/common/admin/login.php index 796011f..a95e59f 100755 --- a/common/admin/login.php +++ b/common/admin/login.php @@ -1,10 +1,13 @@
@@ -31,4 +34,4 @@ FRAGMENT; $page_id = 'admin-login'; $admin_access = 0; -require_once dirname(__FILE__) . '/template.php'; +require_once __DIR__ . '/template.php'; diff --git a/common/admin/logout.php b/common/admin/logout.php index 6dd32aa..adb843f 100644 --- a/common/admin/logout.php +++ b/common/admin/logout.php @@ -1,5 +1,10 @@ \ No newline at end of file +die(); diff --git a/common/admin/purgecache.php b/common/admin/purgecache.php index a5af5cf..23a5712 100644 --- a/common/admin/purgecache.php +++ b/common/admin/purgecache.php @@ -1,16 +1,18 @@ verify($_POST['_csrf'], 'feedmanage')) { + die('Invalid CSRF token!'); +} + if (isset($_POST['opml']) || isset($_POST['add'])) { - // Load config and old OPML - $conf = Spyc::YAMLLoad(dirname(__FILE__).'/../custom/config.yml'); - $PlanetConfig = new PlanetConfig($conf); + // Load old OPML + $oldOpml = OpmlManager::load(__DIR__.'/../custom/people.opml'); if ($PlanetConfig->getName() === '') { $PlanetConfig->setName($oldOpml->getTitle()); } - $oldOpml = OpmlManager::load(dirname(__FILE__).'/../custom/people.opml'); - $newOpml = new opml(); + $newOpml = new Opml(); $newOpml->title = $PlanetConfig->getName(); // Remove slashes if needed @@ -43,11 +46,18 @@ if (isset($_POST['opml']) || isset($_POST['add'])) { $feed = new SimplePie(); $feed->enable_cache(false); $feed->set_feed_url($_POST['url']); + if ($conf['checkcerts'] === false) { + $feed->set_curl_options([ + CURLOPT_SSL_VERIFYHOST => false, + CURLOPT_SSL_VERIFYPEER => false + ]); + } $feed->init(); $feed->handle_content_type(); - $person['name'] = $feed->get_title(); + $person['name'] = html_entity_decode($feed->get_title()); $person['website'] = $feed->get_permalink(); $person['feed'] = $feed->feed_url; + $person['isDown'] = '0'; $oldOpml->entries[] = $person; } @@ -55,10 +65,10 @@ if (isset($_POST['opml']) || isset($_POST['add'])) { } // Backup old OPML - OpmlManager::backup(dirname(__FILE__).'/../custom/people.opml'); + OpmlManager::backup(__DIR__.'/../custom/people.opml'); // Save new OPML - OpmlManager::save($newOpml, dirname(__FILE__).'/../custom/people.opml'); + OpmlManager::save($newOpml, __DIR__.'/../custom/people.opml'); } header("Location: index.php"); die(); diff --git a/common/app/app.php b/common/app/app.php index 0703ac5..0797cc7 100755 --- a/common/app/app.php +++ b/common/app/app.php @@ -1,29 +1,15 @@ time()) { + return true; + } + + @unlink($filename); + + return false; + } + + /** + * Builds a filename/path from group, id and + * store. + * + * @param string $group Group to store data under + * @param string $id Unique ID of this data + */ + protected static function getFilename($group, $id) + { + $id = md5($id); + + return self::$store . self::$prefix . "{$group}_{$id}"; + } + + /** + * Sets the filename prefix to use + * + * @param string $prefix Filename Prefix to use + */ + public static function setPrefix($prefix) + { + self::$prefix = $prefix; + } + + /** + * Sets the store for cache files. Defaults to + * /dev/shm. Must have trailing slash. + * + * @param string $store The dir to store the cache data in + */ + public static function setStore($store) + { + self::$store = $store; + } + } + + /** + * Output Cache extension of base caching class + */ + class OutputCache extends Cache + { + /** + * Group of currently being recorded data + * @var string + */ + private static $group; + + /** + * ID of currently being recorded data + * @var string + */ + private static $id; + + /** + * Ttl of currently being recorded data + * @var int + */ + private static $ttl; + + /** + * Starts caching off. Returns true if cached, and dumps + * the output. False if not cached and start output buffering. + * + * @param string $group Group to store data under + * @param string $id Unique ID of this data + * @param int $ttl How long to cache for (in seconds) + * @return bool True if cached, false if not + */ + public static function Start($group, $id, $ttl) + { + if (self::isCached($group, $id)) { + echo self::read($group, $id); + return true; + + } else { + + ob_start(); + + self::$group = $group; + self::$id = $id; + self::$ttl = $ttl; + + return false; + } + } + + /** + * Ends caching. Writes data to disk. + */ + public static function End() + { + $data = ob_get_contents(); + ob_end_flush(); + + self::write(self::$group, self::$id, self::$ttl, $data); + } + } + + /** + * Data cache extension of base caching class + */ + class DataCache extends Cache + { + + /** + * Retrieves data from the cache + * + * @param string $group Group this data belongs to + * @param string $id Unique ID of the data + * @return mixed Either the resulting data, or null + */ + public static function Get($group, $id) + { + if (self::isCached($group, $id)) { + return unserialize(self::read($group, $id)); + } + + return null; + } + + /** + * Stores data in the cache + * + * @param string $group Group this data belongs to + * @param string $id Unique ID of the data + * @param int $ttl How long to cache for (in seconds) + * @param mixed $data The data to store + */ + public static function Put($group, $id, $ttl, $data) + { + self::write($group, $id, $ttl, serialize($data)); + } + } +?> \ No newline at end of file diff --git a/common/app/classes/Opml.php b/common/app/classes/Opml.php new file mode 100644 index 0000000..ae9e8b1 --- /dev/null +++ b/common/app/classes/Opml.php @@ -0,0 +1,70 @@ + 'website', + 'HTMLURL' => 'website', + 'TEXT' => 'name', + 'TITLE' => 'name', + 'XMLURL' => 'feed', + 'DESCRIPTION' => 'description', + 'ISDOWN' => 'isDown' + ); + + + function parse($data) + { + $this->_xml = xml_parser_create('UTF-8'); + //xml_parser_set_option($this->_xml, XML_OPTION_CASE_FOLDING, false); + //xml_parser_set_option($this->_xml, XML_OPTION_SKIP_WHITE, true); + xml_set_object($this->_xml, $this); + xml_set_element_handler($this->_xml,'_openTag','_closeTag'); + xml_set_character_data_handler ($this->_xml, '_cData'); + + xml_parse($this->_xml,$data); + xml_parser_free($this->_xml); + return $this->entries; + } + + + function _openTag($p,$tag,$attrs) + { + $this->_currentTag = $tag; + + if ($tag == 'OUTLINE') + { + $i = count($this->entries); + foreach (array_keys($this->map) as $key) + { + if (isset($attrs[$key])) { + $this->entries[$i][$this->map[$key]] = $attrs[$key]; + } + } + } + } + + function _closeTag($p, $tag){ + $this->_currentTag = ''; + } + + function _cData($p, $cdata){ + if ($this->_currentTag == 'TITLE'){ + $this->title = $cdata; + } + } + + function getTitle(){ + return $this->title; + } + + function getPeople(){ + return $this->entries; + } +} \ No newline at end of file diff --git a/common/app/classes/OpmlManager.php b/common/app/classes/OpmlManager.php new file mode 100644 index 0000000..d3940b2 --- /dev/null +++ b/common/app/classes/OpmlManager.php @@ -0,0 +1,50 @@ +parse($fileContent); + + return $opml; + } + + /** + * @param Opml $opml + * @param string $file + */ + public static function save($opml, $file){ + $out = ''."\n"; + $out.= ''."\n"; + $out.= ''."\n"; + $out.= ''.htmlspecialchars($opml->getTitle()).''."\n"; + $out.= ''.date('c').''."\n"; + $out.= ''.date('c').''."\n"; + $out.= ''."\n"; + $out.= ''."\n"; + foreach ($opml->entries as $person) { + $out.= ''."\n"; + } + $out.= ''."\n"; + $out.= ''; + + file_put_contents($file, $out); + } + + public static function backup($file){ + copy($file, $file.'.bak'); + } +} diff --git a/common/app/classes/Planet.php b/common/app/classes/Planet.php new file mode 100644 index 0000000..b146eaf --- /dev/null +++ b/common/app/classes/Planet.php @@ -0,0 +1,266 @@ +config = $config === null ? new PlanetConfig() : $config; + + $this->items = []; + $this->people = []; + $this->errors = []; + } + + /** + * Compare the supplied password with the known one. + * + * This functions uses a type-safe and timing-safe comparison, in order to + * improve the security of the authentication. + * + * Read more about this sort of attacks (used for the < PHP 5.6.0 implementation): + * - https://security.stackexchange.com/questions/83660/simple-string-comparisons-not-secure-against-timing-attacks + * - https://github.com/laravel/framework/blob/a1dc78820d2dbf207dbdf0f7075f17f7021c4ee8/src/Illuminate/Support/Str.php#L289 + * - https://github.com/symfony/security-core/blob/master/Util/StringUtils.php#L39 + * + * @param string $known + * @param string $supplied + * @return bool + */ + public static function authenticateUser($known = '', $supplied = '') + { + // The hash_equals function was introduced in PHP 5.6.0. If it's not + // existing in the current context (PHP version too old), and to ensure + // compatibility with those old interpreters, we'll have to provide + // an PHP implementation of this function. + if (function_exists('hash_equals')) { + return hash_equals($known, $supplied); + } + + // Some implementation references can be found on the function comment. + $knownLen = mb_strlen($known); + if ($knownLen !== mb_strlen($supplied)) { + return false; + } + + // Ensure that all the characters are the same, and continue until the + // end of the string even if an difference was found. + for ($i = 0, $comparison = 0; $i < $knownLen; $i++) { + $comparison |= ord($known[$i]) ^ ord($supplied[$i]); + } + + return ($comparison === 0); + } + + /** + * Getters + */ + public function getItems() + { + $this->items = $this->_filterItemsByCategory( + $this->items, + $this->config->getCategories()); + + return $this->items; + } + + public function getPeople() + { + return $this->people; + } + + /** + * Adds a feed to the planet. + * + * @param PlanetFeed $feed + */ + public function addPerson(&$feed) + { + $this->people[] = $feed; + } + + /** + * Load people from an OPML. + * + * @param string $file File to load the OPML from. + * @return integer Number of people loaded. + */ + public function loadOpml($file) + { + if (!is_file($file)) { + $this->errors[] = new PlanetError(3, $file.' is missing.'); + return 0; + } + + $opml = OpmlManager::load($file); + $opml_people = $opml->getPeople(); + foreach ($opml_people as $opml_person){ + $person = new PlanetFeed( + $opml_person['name'], + $opml_person['feed'], + $opml_person['website'], + $opml_person['isDown'] + ); + $this->addPerson($person); + } + return count($opml_people); + } + + /** + * Load feeds + */ + public function loadFeeds() + { + foreach ($this->people as $feed) { + //Is down it's filled by cron.php, $Planet->download(1.0) proccess + if (!$feed->isDown) { + $feed->set_timeout(-1); + $feed->init(); + $this->items = array_merge($this->items, $feed->get_items()); + } + + } + $this->sort(); + } + + /** + * Fetch feeds and see if new data is present. + * + * @param float $max_load Percentage of feeds to load + */ + public function download($max_load=0.1) + { + $max_load_feeds = ceil(count($this->people) * $max_load); + $opml = OpmlManager::load(__DIR__.'/../../custom/people.opml'); + + foreach ($this->people as $feed) { + //Avoid mass loading with variable cache duration + $feed->set_cache_duration($this->config->getCacheTimeout()); + + //Load only a few feeds, force other to fetch from the cache + if (0 > $max_load_feeds--) { + $feed->set_timeout(-1); + $this->errors[] = new PlanetError(1, 'Forced from cache : '.$feed->getFeed()); + } + + // Bypass remote's SSL/TLS certificate if the user explicitly + // asked for it in the configuration. + if ($this->config->checkcerts === false) { + $feed->set_curl_options([ + CURLOPT_SSL_VERIFYHOST => false, + CURLOPT_SSL_VERIFYPEER => false + ]); + } + + $feed->init(); + $isDown = ''; + + // http://simplepie.org/wiki/reference/simplepie/merge_items ? + if (($feed->data) && ($feed->get_item_quantity() > 0)){ + $items = $feed->get_items(); + $this->items = array_merge($this->items, $items); + } else { + $this->errors[] = new PlanetError(1, 'No items or down : ' . $feed->getFeed()); + $isDown = '1'; + } + + foreach ($opml->entries as $key => $entrie) { + if ($feed->getFeed() === $entrie['feed']) { + $opml->entries[$key]['isDown'] = $isDown; + } + } + } + + OpmlManager::save($opml, __DIR__.'/../../custom/people.opml'); + } + + public function sort() + { + usort($this->items, array('PlanetItem','compare')); + } + + /** + * Filter out items that do not match at least one + * of the defined categories. + * + * If there's no category, return all items. + * + * @param array $items to filter + * @param string $categories to filter against; may be a single word + * or a comma-separated list of words. + * + * @return array resulting list of items + */ + public function _filterItemsByCategory($items, $categories = null) + { + $categories = trim($categories); + + if (empty($categories)) + return $items; + + $categories = array_map('trim', explode(',', strtolower($categories))); + $cb_category_filter = + function ($item) use ($categories) + { + if (!is_array($item_categories = $item->get_categories())) + return false; + + $item_categories = array_map( + function ($i) { return strtolower($i->get_label()); }, + $item_categories + ); + + return array_intersect($categories, $item_categories); + }; + + return array_values(array_filter($items, $cb_category_filter)); + } +} diff --git a/common/app/classes/PlanetConfig.php b/common/app/classes/PlanetConfig.php index a31938e..f3928bc 100644 --- a/common/app/classes/PlanetConfig.php +++ b/common/app/classes/PlanetConfig.php @@ -6,32 +6,45 @@ class PlanetConfig { - public $conf; - - public function __construct($array) - { - $defaultConfig = array( - 'url' => 'http://www.example.com/', - 'name' => '', - 'locale' => 'en', - 'items' => 10, - 'shuffle' => 0, - 'refresh' => 240, - 'cache' => 10, - 'nohtml' => 0, - 'postmaxlength' => 0, - 'cachedir' => './cache', - ); - - // User config - $this->conf = $array; - - // Complete config with default config - foreach ($defaultConfig as $key => $value) { - if (!isset($this->conf[$key])) { - $this->conf[$key] = $value; - } - } + protected $conf = []; + + public static $defaultConfig = [ + 'url' => 'http://www.example.com/', + 'name' => '', + 'locale' => 'en', + 'items' => 10, + 'shuffle' => 0, + 'refresh' => 240, + 'cache' => 10, + 'nohtml' => 0, + 'postmaxlength' => 0, + 'categories' => '', + 'cachedir' => './cache', + 'debug' => false, + 'checkcerts' => true, + ]; + + /** + * PlanetConfig constructor. + * @param array $userConfig + * @param bool $useDefaultConfig + */ + public function __construct($userConfig = [], $useDefaultConfig = true) + { + $default = $useDefaultConfig ? self::$defaultConfig : array(); + $this->conf = $this->merge($default, $userConfig); + } + + /** + * Merge the configuration of the user in the default one. + * + * @param array $default + * @param array $user + * @return array + */ + protected function merge($default = [], $user = []) + { + return array_merge($default, $this->normalizeArrayKeys($user)); } public function getUrl() @@ -58,7 +71,10 @@ class PlanetConfig return $this->conf['cache']; } - //@TODO: drop this pref + /** + * @deprecated + * @return mixed + */ public function getShuffle() { return $this->conf['shuffle']; @@ -69,20 +85,110 @@ class PlanetConfig return $this->conf['items']; } - //@TODO: drop this pref + /** + * @deprecated + * @return mixed + */ public function getNoHTML() { return $this->conf['nohtml']; } - //@TODO: drop this pref + /** + * @deprecated + * @return mixed + */ public function getPostMaxLength() { return $this->conf['postmaxlength']; } + public function getCategories() + { + return $this->conf['categories']; + } + public function toYaml() { - return Spyc::YAMLDump($this->conf,4); + return Spyc::YAMLDump($this->conf, 4); + } + + /** + * @return array + */ + public function toArray() + { + return $this->conf; + } + + public function getDebug() + { + return $this->conf['debug']; + } + + /** + * @return array + */ + public function getDefaultConfig() + { + return self::$defaultConfig; + } + + /** + * Normalize the name of a configuration key. + * + * @param string $key + * @return string + */ + protected function normalizeKeyName($key = null) + { + return strtolower($key); + } + + /** + * Normalize all the keys of the array. + * + * @param array $array + * @return array + */ + protected function normalizeArrayKeys($array = []) + { + foreach ($array as $key => $value) { + $normalized = $this->normalizeKeyName($key); + if ($normalized !== $key) { + $array[$this->normalizeKeyName($key)] = $value; + unset($array[$key]); + } + } + + return $array; } + + /** + * Generic configuration getter. + * + * @return mixed|null + */ + public function __get($key) + { + $key = $this->normalizeKeyName($key); + + return array_key_exists($key, $this->conf) ? + $this->conf[$key] : + null; + } + + /** + * Generic configuration setter. + * + * @param $key + * @param $value + */ + public function __set($key, $value) + { + $key = $this->normalizeKeyName($key); + + $this->conf[$key] = $value; + } + } diff --git a/common/app/classes/PlanetError.php b/common/app/classes/PlanetError.php index 31923a3..e47ab1d 100644 --- a/common/app/classes/PlanetError.php +++ b/common/app/classes/PlanetError.php @@ -3,21 +3,30 @@ class PlanetError { public $level; + public $levels = array( + 1 => 'notice', + 2 => 'warning', + 3 => 'error', + ); public $message; + /** + * PlanetError constructor. + * @param $level + * @param $message + */ public function __construct($level, $message) { $this->level = (int) $level; $this->message = $message; } - public function toString($format = '%1$s : %2$s') + /** + * @param string $format + * @return string + */ + public function toString($format = '%1$s: %2$s') { - $levels = array( - 1 => 'notice', - 2 => 'warning', - 3 => 'error', - ); - return sprintf($format, $levels[$this->level], $this->message); + return sprintf($format, $this->levels[$this->level], $this->message); } } diff --git a/common/app/classes/PlanetFeed.php b/common/app/classes/PlanetFeed.php index a6c7aab..3d2ea2f 100644 --- a/common/app/classes/PlanetFeed.php +++ b/common/app/classes/PlanetFeed.php @@ -9,15 +9,17 @@ class PlanetFeed extends SimplePie public $name; public $feed; public $website; + public $isDown; - public function __construct($name, $feed, $website) + public function __construct($name, $feed, $website, $isDown) { $this->name = $name; $this->feed = $feed; $this->website = $website; + $this->isDown = $isDown; parent::__construct(); $this->set_item_class('PlanetItem'); - $this->set_cache_location(dirname(__FILE__).'/../../cache'); + $this->set_cache_location(__DIR__.'/../../cache'); $this->set_autodiscovery_level(SIMPLEPIE_LOCATOR_NONE); $this->set_feed_url($this->getFeed()); $this->set_timeout(5); @@ -39,7 +41,19 @@ class PlanetFeed extends SimplePie return $this->website; } - public function compare($person1, $person2) + public function getIsDown() + { + return $this->isDown; + } + + /** + * Compare two Person by their name. + * + * @param $person1 + * @param $person2 + * @return int + */ + public static function compare($person1, $person2) { return strcasecmp($person1->name, $person2->name); } diff --git a/common/app/classes/PlanetItem.php b/common/app/classes/PlanetItem.php index 039d0ca..7d55781 100644 --- a/common/app/classes/PlanetItem.php +++ b/common/app/classes/PlanetItem.php @@ -4,14 +4,19 @@ * Planet item */ -class PlanetItem +class PlanetItem extends SimplePie_Item { public function __construct($feed, $data) { - parent::SimplePie_Item($feed, $data); + parent::__construct($feed, $data); } - public function compare($item1, $item2) + /** + * @param PlanetItem $item1 + * @param PlanetItem $item2 + * @return int + */ + public static function compare($item1, $item2) { $item1_date = $item1->get_date('U'); $item2_date = $item2->get_date('U'); diff --git a/common/app/classes/Simplel10n.php b/common/app/classes/Simplel10n.php new file mode 100755 index 0000000..79313b3 --- /dev/null +++ b/common/app/classes/Simplel10n.php @@ -0,0 +1,52 @@ +locale = $locale; + $this->l10nFolder = __DIR__ . '/../l10n/'; + $this->load($this->l10nFolder . $this->locale); + } + + public function setL1OnFolder($path) { + $this->l10nFolder = $path; + } + + static function getString($str, $comment='') { + if(array_key_exists($str, $GLOBALS['locale'])) { + return trim(str_replace('{ok}', '', $GLOBALS['locale'][$str])); + } else { + return $str; + } + } + + /* + * This is the same as getString except that we don't remove the {ok} string + * This is needed only for the extraction script + */ + static function extractString($str, $comment='') { + if(array_key_exists($str, $GLOBALS['locale'])) { + return $GLOBALS['locale'][$str]; + } else { + return $str; + } + } + + static function load($pathToFile) { + + if (!file_exists($pathToFile . '.lang')) return false; + + $file = file($pathToFile . '.lang'); + + foreach ($file as $k => $v) { + if (substr($v,0,1) == ';' && !empty($file[$k+1])) { + $GLOBALS['locale'][trim(substr($v,1))] = trim($file[$k+1]); + } + } + } +} diff --git a/common/app/helpers.php b/common/app/helpers.php new file mode 100644 index 0000000..e943252 --- /dev/null +++ b/common/app/helpers.php @@ -0,0 +1,130 @@ +moonmoon +Powered by moonmoon + + +;No article +Kein Artikel + + +;No news, good news. +Keine Neuigkeiten, gute Neuigkeiten. + + +;Today +Heute + + +;Go to original place +Gehe zur Originalseite + + +;This week +Diese Woche + + +;This month +Diesen Monat + + +;Older items +Ältere Einträge + + +;People +Personen + + +;Feed +Feed + + +;Website +Webseite + + +;All feeds in OPML format +Alle Feeds im OPML-Format + + +;Syndicate +Zusammenfassung + + +;Feed (ATOM) +Feed (ATOM) + + +;Archives +Archive + + +;See all headlines +Alle Schlagzeilen ansehen + + +;Source: +Quelle: + + +;You might want to install moonmoon. +Sie könnten moonmoon installieren wollen. + + +;moonmoon installation +moonmoon Installation + + +;Congratulations! Your moonmoon is ready. +Gratulation! Ihr moonmoon ist bereit. + + +;What's next? +Was nun? + + +;Delete install.php with your FTP software. +Entfernen Sie install.php mit Ihrer FTP-Software. + + +;Use your password to go to the administration panel +Verwenden Sie Ihr Passwort, um zum Administrationsbereich zu gehen. + + diff --git a/common/app/l10n/en.lang b/common/app/l10n/en.lang index 64d5a82..ff49307 100644 --- a/common/app/l10n/en.lang +++ b/common/app/l10n/en.lang @@ -113,6 +113,10 @@ Website link Feed link +# Translation note: ** String needs translation ** +;Unavailable +Unavailable + # Translation note: ** String needs translation ** ;Not in cache Not in cache diff --git a/common/app/l10n/es.lang b/common/app/l10n/es.lang new file mode 100644 index 0000000..11b80df --- /dev/null +++ b/common/app/l10n/es.lang @@ -0,0 +1,244 @@ +# Translation note: ¿Está seguro que desea vaciar la caché? +;Are you sure you want to purge the cache? +¿Está seguro de que desea vaciar la caché? + + +# Translation note: Vaciar la caché +;Clear cache +Vaciar la caché + + +# Translation note: Vaciar la caché: +;Clear cache: +Vaciar la caché: + + +;Clear +Vaciar + + +# Translation note: Vaciar la caché hará que moonmoon recargue todas las fuentes web. +;Clearing the cache will make moonmoon reload all feeds. +Vaciar la caché hará que moonmoon recargue todas las fuentes web. + + +# Translation note: Cambiar la contraseña de administración +;Change administrator password +Cambiar la contraseña de administración + + +# Translation note: Nueva contraseña: +;New password: +Nueva contraseña: + + +# Translation note: Cambiar la contraseña +;Change password +Cambiar la contraseña + + +# Translation note: Añadir una nueva fuente web - 'feed' = 'fuente web', 'fuente' or 'canal' in spanish, but you can use 'feed' anyway. +;Add a new feed +Añadir una nueva fuente web + + +# Translation note: Añadir fuente +;Add Feed +Añadir fuente + + +;Link: +Enlace: + + +# Translation note: Los formatos aceptados son RSS y ATOM. Si el enlace no es una fuente web, moonmoon tratará de encontrar la fuente de forma automática. +;Accepted formats are RSS and ATOM. If the link is not a feed, moonmoon will try to autodiscover the feed. +Los formatos aceptados son RSS y ATOM. Si el enlace no es una fuente web, moonmoon tratará de encontrar la fuente de forma automática. + + +;Manage existing feeds +Administrar las fuentes existentes + + +# Translation note: Número de fuentes +;Number of feeds: %s +Número de fuentes: %s + + +;Save changes +Guardar cambios + + +;Delete selected Feeds +Borrar seleccionadas + + +;Select : +Seleccionar: + + +;All +Todas + + +;None +Ninguna + + +# Translation note: Selección +;Selection +Selección + + +;Name +Nombre + +# Translation note: Última entrada +;Last entry +Última entrada + + +;Website link +Enlace a la web + + +;Feed link +Enlace a la fuente + + +# Translation note: 'No está en caché' or 'No en caché' +;Not in cache +No está en caché + + +# Translation note: Contraseña: +;Password: +Contraseña: + + +;OK +Entrar + + +# Translation note: Administración de moonmoon +;moonmoon administration +Administración de moonmoon + + +# Translation note: Volver a la página principal +;Back to main page +Volver a la página principal + + +;Logout +Salir + + +;Feeds +Fuentes + + +# Translation note: Administración +;Administration +Administración + + +;Powered by moonmoon +Desarrollado por moonmoon + + +# Translation note: Sin artículos +;No article +Sin artículos + + +;No news, good news. +No hay noticias, buena noticia. + + +;Today +Hoy + + +# Translation note: Ir a la ubicación original +;Go to original place +Ir a la ubicación original + + +;This week +Esta semana + + +;This month +Este mes + + +;Older items +Titulares anteriores + + +# Translation note: 'People' = 'Personas', but 'fuentes'(sources), which in Spanish means origins, is more generic. +;People +Fuentes + + +;Feed +Fuente + + +;Website +Sitio web + + +;All feeds in OPML format +Todas las fuentes (OPML) + + +# Translation note: Redifusión +;Syndicate +Redifusión + + +;Feed (ATOM) +Fuente (ATOM) + + +;Archives +Archivos + + +;See all headlines +Ver todos los titulares + + +# Translation note: You may use 'Source' = 'Origen' too. +;Source: +Fuente: + + +;You might want to install moonmoon. +Es posible que desee instalar moonmoon. + + +# Translation note: Instalación de moonmoon +;moonmoon installation +Instalación de moonmoon + + +# Translation note: ¡Felicidades! Su moonmoon está preparado. +;Congratulations! Your moonmoon is ready. +¡Felicidades! Su moonmoon está preparado. + + +# Translation note: ¿Y ahora? +;What's next? +¿Y ahora? + + +;Delete install.php with your FTP software. +Borre install.php con su programa de FTP. + + +# Translation note: Utilice su contraseña para acceder al panel de administración. +;Use your password to go to the administration panel +Utilice su contraseña para acceder al panel de administración. diff --git a/common/app/l10n/extract.php b/common/app/l10n/extract.php index 1a04f00..1384827 100755 --- a/common/app/l10n/extract.php +++ b/common/app/l10n/extract.php @@ -13,13 +13,15 @@ * The script scans for the files in the l10n/ folder to know which locales are supported */ -// released versions of moonmoon should immediately return for security -// return; +$root = __DIR__ . '/../../'; -$root = dirname(__FILE__) . '/../../'; -$GLOBALS['english'] = array(); +require_once __DIR__ . '/../app.php'; -include_once $root . '/app/classes/Simplel10n.class.php'; +if ($conf['debug'] !== true) { + die('Please enable the debug mode to use extract.php.'); +} + +$GLOBALS['english'] = array(); /* * This is a file parser to extract localizable strings (in .php files) @@ -27,7 +29,6 @@ include_once $root . '/app/classes/Simplel10n.class.php'; * */ - function extract_l10n_strings($file) { $lines = file($file); $patterns = array('/_g\([\'"](.*?)[\'"]\)/', '/getString\([\'"](.*?)[\'"]\)/',); diff --git a/common/app/l10n/fr.lang b/common/app/l10n/fr.lang index 6247652..4e2a568 100755 --- a/common/app/l10n/fr.lang +++ b/common/app/l10n/fr.lang @@ -90,6 +90,10 @@ Lien du site Lien du Flux +;Unavailable +Indisponible + + ;Not in cache Pas en cache diff --git a/common/atom.php b/common/atom.php index 5122158..c80d987 100644 --- a/common/atom.php +++ b/common/atom.php @@ -1,15 +1,15 @@ loadOpml(dirname(__FILE__).'/custom/people.opml') == 0) exit; +if ($Planet->loadOpml(__DIR__.'/custom/people.opml') == 0) exit; $Planet->loadFeeds(); $items = $Planet->getItems(); $limit = $PlanetConfig->getMaxDisplay(); $count = 0; -header('Content-Type: application/atom+xml; charset=UTF-8'); +header('Content-Type: text/xml; charset=UTF-8'); echo ''; ?> diff --git a/common/bin/build_release.sh b/common/bin/build_release.sh new file mode 100755 index 0000000..2f09661 --- /dev/null +++ b/common/bin/build_release.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +set -eu + +tmp=$(mktemp -d -t moonmmon) + +echo "[*] Building into $tmp..." + +cd "$tmp" +git clone https://github.com/moonmoon/moonmoon.git --depth=1 --recursive -j8 +cd moonmoon +composer install --no-suggest --prefer-dist --no-dev +git describe --abbrev=0 --tags > VERSION +find . -name .DS_Store -exec rm {} \; +rm -rf .git .github .travis.yml .gitignore .gitmodules docs/.git/ +mkdir cache +cd .. +zip -r "moonmoon-$(cat moonmoon/VERSION).zip" . + +echo "[*] Grab the archive: ${tmp}/moonmoon-$(cat moonmoon/VERSION).zip" diff --git a/common/composer.json b/common/composer.json new file mode 100644 index 0000000..ea5032d --- /dev/null +++ b/common/composer.json @@ -0,0 +1,35 @@ +{ + "name": "mauricesvay/moonmoon", + "description": "Moonmoon is a simple feed aggregator.", + "homepage": "http://moonmoon.org/", + "type": "project", + "license": "BSD", + "authors": [ + { + "name": "Maurice Svay", + "email": "maurice@svay.com" + } + ], + "minimum-stability": "stable", + "require": { + "php": "^5.6 || ^7.0", + "mustangostang/spyc": "0.5.1", + "simplepie/simplepie": "^1.5", + "paragonie/random_compat": "^2.0" + }, + "require-dev": { + "guzzlehttp/guzzle": "^6.3", + "phpunit/phpunit": "^5.7 || ^6.2" + }, + "scripts": { + "test": "" + }, + "autoload": { + "psr-0": { + "": "app/classes/" + }, + "files": [ + "app/helpers.php" + ] + } +} diff --git a/common/composer.lock b/common/composer.lock new file mode 100644 index 0000000..7959c9c --- /dev/null +++ b/common/composer.lock @@ -0,0 +1,1599 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "This file is @generated automatically" + ], + "content-hash": "a4fc919a4e8ef2463ff4a336940bc993", + "packages": [ + { + "name": "mustangostang/spyc", + "version": "0.5.1", + "source": { + "type": "git", + "url": "https://github.com/mustangostang/spyc.git", + "reference": "dc4785b4d7227fd9905e086d499fb8abfadf9977" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mustangostang/spyc/zipball/dc4785b4d7227fd9905e086d499fb8abfadf9977", + "reference": "dc4785b4d7227fd9905e086d499fb8abfadf9977", + "shasum": "" + }, + "require": { + "php": ">=5.3.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.5.x-dev" + } + }, + "autoload": { + "files": [ + "Spyc.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT License" + ], + "authors": [ + { + "name": "mustangostang", + "email": "vlad.andersen@gmail.com" + } + ], + "description": "A simple YAML loader/dumper class for PHP", + "homepage": "https://github.com/mustangostang/spyc/", + "keywords": [ + "spyc", + "yaml", + "yml" + ], + "time": "2013-02-21T10:52:01+00:00" + }, + { + "name": "paragonie/random_compat", + "version": "v2.0.11", + "source": { + "type": "git", + "url": "https://github.com/paragonie/random_compat.git", + "reference": "5da4d3c796c275c55f057af5a643ae297d96b4d8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/5da4d3c796c275c55f057af5a643ae297d96b4d8", + "reference": "5da4d3c796c275c55f057af5a643ae297d96b4d8", + "shasum": "" + }, + "require": { + "php": ">=5.2.0" + }, + "require-dev": { + "phpunit/phpunit": "4.*|5.*" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + }, + "type": "library", + "autoload": { + "files": [ + "lib/random.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "pseudorandom", + "random" + ], + "time": "2017-09-27T21:40:39+00:00" + }, + { + "name": "simplepie/simplepie", + "version": "1.5", + "source": { + "type": "git", + "url": "https://github.com/simplepie/simplepie.git", + "reference": "5de5551953f95feef12cf355a7a26a70f94aa3ab" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/simplepie/simplepie/zipball/5de5551953f95feef12cf355a7a26a70f94aa3ab", + "reference": "5de5551953f95feef12cf355a7a26a70f94aa3ab", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "~4 || ~5" + }, + "suggest": { + "mf2/mf2": "Microformat module that allows for parsing HTML for microformats" + }, + "type": "library", + "autoload": { + "psr-0": { + "SimplePie": "library" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Ryan Parman", + "homepage": "http://ryanparman.com/", + "role": "Creator, alumnus developer" + }, + { + "name": "Geoffrey Sneddon", + "homepage": "http://gsnedders.com/", + "role": "Alumnus developer" + }, + { + "name": "Ryan McCue", + "email": "me@ryanmccue.info", + "homepage": "http://ryanmccue.info/", + "role": "Developer" + } + ], + "description": "A simple Atom/RSS parsing library for PHP", + "homepage": "http://simplepie.org/", + "keywords": [ + "atom", + "feeds", + "rss" + ], + "time": "2017-04-17T07:29:31+00:00" + } + ], + "packages-dev": [ + { + "name": "dflydev/markdown", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/dflydev/dflydev-markdown.git", + "reference": "76501a808522dbe40a5a71d272bd08d54cbae03d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dflydev/dflydev-markdown/zipball/76501a808522dbe40a5a71d272bd08d54cbae03d", + "reference": "76501a808522dbe40a5a71d272bd08d54cbae03d", + "shasum": "" + }, + "require": { + "php": ">=5.3" + }, + "type": "library", + "autoload": { + "psr-0": { + "dflydev\\markdown": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "New BSD License" + ], + "authors": [ + { + "name": "Dragonfly Development Inc.", + "email": "info@dflydev.com", + "homepage": "http://dflydev.com" + }, + { + "name": "Beau Simensen", + "email": "beau@dflydev.com", + "homepage": "http://beausimensen.com" + }, + { + "name": "Michel Fortin", + "homepage": "http://michelf.com" + }, + { + "name": "John Gruber", + "homepage": "http://daringfireball.net" + } + ], + "description": "PHP Markdown & Extra", + "homepage": "http://github.com/dflydev/dflydev-markdown", + "keywords": [ + "markdown" + ], + "abandoned": "michelf/php-markdown", + "time": "2012-01-02T23:11:32+00:00" + }, + { + "name": "doctrine/instantiator", + "version": "1.0.4", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "f976e5de371104877ebc89bd8fecb0019ed9c119" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/f976e5de371104877ebc89bd8fecb0019ed9c119", + "reference": "f976e5de371104877ebc89bd8fecb0019ed9c119", + "shasum": "" + }, + "require": { + "php": ">=5.3,<8.0-DEV" + }, + "require-dev": { + "athletic/athletic": "~0.1.8", + "ext-pdo": "*", + "ext-phar": "*", + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "2.0.*@ALPHA" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "Doctrine\\Instantiator\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://github.com/doctrine/instantiator", + "keywords": [ + "constructor", + "instantiate" + ], + "time": "2014-10-13T12:58:55+00:00" + }, + { + "name": "guzzlehttp/guzzle", + "version": "6.3.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "f4db5a78a5ea468d4831de7f0bf9d9415e348699" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/f4db5a78a5ea468d4831de7f0bf9d9415e348699", + "reference": "f4db5a78a5ea468d4831de7f0bf9d9415e348699", + "shasum": "" + }, + "require": { + "guzzlehttp/promises": "^1.0", + "guzzlehttp/psr7": "^1.4", + "php": ">=5.5" + }, + "require-dev": { + "ext-curl": "*", + "phpunit/phpunit": "^4.0 || ^5.0", + "psr/log": "^1.0" + }, + "suggest": { + "psr/log": "Required for using the Log middleware" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.2-dev" + } + }, + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle is a PHP HTTP client library", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "rest", + "web service" + ], + "time": "2017-06-22T18:50:49+00:00" + }, + { + "name": "guzzlehttp/promises", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "01abc3232138f330d8a1eaa808fcbdf9b4292f47" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/01abc3232138f330d8a1eaa808fcbdf9b4292f47", + "reference": "01abc3232138f330d8a1eaa808fcbdf9b4292f47", + "shasum": "" + }, + "require": { + "php": ">=5.5.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + }, + "files": [ + "src/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle promises library", + "keywords": [ + "promise" + ], + "time": "2015-05-13T05:05:10+00:00" + }, + { + "name": "guzzlehttp/psr7", + "version": "1.4.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "04a6d1a00ea5da0727ee94309a9f0d3dbaecb569" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/04a6d1a00ea5da0727ee94309a9f0d3dbaecb569", + "reference": "04a6d1a00ea5da0727ee94309a9f0d3dbaecb569", + "shasum": "" + }, + "require": { + "php": ">=5.4.0", + "psr/http-message": "~1.0" + }, + "provide": { + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Schultze", + "homepage": "https://github.com/Tobion" + } + ], + "description": "PSR-7 message implementation that also provides common utility methods", + "keywords": [ + "http", + "message", + "request", + "response", + "stream", + "uri", + "url" + ], + "time": "2017-02-21T01:20:32+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "96fbdc07635989c35c5a1912379f4c4b2ab15fd5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/96fbdc07635989c35c5a1912379f4c4b2ab15fd5", + "reference": "96fbdc07635989c35c5a1912379f4c4b2ab15fd5", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "require-dev": { + "doctrine/collections": "1.*", + "phpunit/phpunit": "~4.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "homepage": "https://github.com/myclabs/DeepCopy", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "time": "2015-03-21T22:40:23+00:00" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "66ae84e9d7c8ea85c979cb65977bd8e608baf0c5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/66ae84e9d7c8ea85c979cb65977bd8e608baf0c5", + "reference": "66ae84e9d7c8ea85c979cb65977bd8e608baf0c5", + "shasum": "" + }, + "require": { + "dflydev/markdown": "1.0.*", + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "3.7.*@stable" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "phpDocumentor": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "mike.vanriel@naenius.com" + } + ], + "time": "2013-08-07T11:04:22+00:00" + }, + { + "name": "phpspec/prophecy", + "version": "v1.3.1", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "9ca52329bcdd1500de24427542577ebf3fc2f1c9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/9ca52329bcdd1500de24427542577ebf3fc2f1c9", + "reference": "9ca52329bcdd1500de24427542577ebf3fc2f1c9", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "~1.0,>=1.0.2", + "phpdocumentor/reflection-docblock": "~2.0" + }, + "require-dev": { + "phpspec/phpspec": "~2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "psr-0": { + "Prophecy\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "http://phpspec.org", + "keywords": [ + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" + ], + "time": "2014-11-17T16:23:49+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "4.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "903fd6318d0a90b4770a009ff73e4a4e9c437929" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/903fd6318d0a90b4770a009ff73e4a4e9c437929", + "reference": "903fd6318d0a90b4770a009ff73e4a4e9c437929", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0", + "phpunit/php-file-iterator": "~1.3", + "phpunit/php-text-template": "~1.2", + "phpunit/php-token-stream": "^1.4.2", + "sebastian/code-unit-reverse-lookup": "~1.0", + "sebastian/environment": "^1.3.2 || ^2.0", + "sebastian/version": "~1.0|~2.0" + }, + "require-dev": { + "ext-xdebug": ">=2.1.4", + "phpunit/phpunit": "^5.4" + }, + "suggest": { + "ext-dom": "*", + "ext-xdebug": ">=2.4.0", + "ext-xmlwriter": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "time": "2016-11-28T16:00:31+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "1.4.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "a923bb15680d0089e2316f7a4af8f437046e96bb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/a923bb15680d0089e2316f7a4af8f437046e96bb", + "reference": "a923bb15680d0089e2316f7a4af8f437046e96bb", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "time": "2015-04-02T05:19:05+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/206dfefc0ffe9cebf65c413e3d0e809c82fbf00a", + "reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "Text/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "time": "2014-01-30T17:20:04+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "1.0.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "83fe1bdc5d47658b727595c14da140da92b3d66d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/83fe1bdc5d47658b727595c14da140da92b3d66d", + "reference": "83fe1bdc5d47658b727595c14da140da92b3d66d", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "time": "2015-06-13T07:35:30+00:00" + }, + { + "name": "phpunit/php-token-stream", + "version": "1.4.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-token-stream.git", + "reference": "db63be1159c81df649cd0260e30249a586d4129e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/db63be1159c81df649cd0260e30249a586d4129e", + "reference": "db63be1159c81df649cd0260e30249a586d4129e", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Wrapper around PHP's tokenizer extension.", + "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "keywords": [ + "tokenizer" + ], + "time": "2015-06-12T07:34:24+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "5.7.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "00d72b8dbd2bb7d6f02a820e6db5cb70df6ac55c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/00d72b8dbd2bb7d6f02a820e6db5cb70df6ac55c", + "reference": "00d72b8dbd2bb7d6f02a820e6db5cb70df6ac55c", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "myclabs/deep-copy": "~1.3", + "php": "^5.6 || ^7.0", + "phpspec/prophecy": "^1.3.1", + "phpunit/php-code-coverage": "^4.0.3", + "phpunit/php-file-iterator": "~1.4", + "phpunit/php-text-template": "~1.2", + "phpunit/php-timer": "^1.0.6", + "phpunit/phpunit-mock-objects": "^3.2", + "sebastian/comparator": "~1.2.2", + "sebastian/diff": "~1.2", + "sebastian/environment": "^1.3.4 || ^2.0", + "sebastian/exporter": "~2.0", + "sebastian/global-state": "~1.0", + "sebastian/object-enumerator": "~2.0", + "sebastian/resource-operations": "~1.0", + "sebastian/version": "~1.0|~2.0", + "symfony/yaml": "~2.1|~3.0" + }, + "conflict": { + "phpdocumentor/reflection-docblock": "3.0.2" + }, + "require-dev": { + "ext-pdo": "*" + }, + "suggest": { + "ext-xdebug": "*", + "phpunit/php-invoker": "~1.1" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.7.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "time": "2016-12-01T17:04:00+00:00" + }, + { + "name": "phpunit/phpunit-mock-objects", + "version": "3.4.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", + "reference": "45026c8383187ad1dcb14fbfec77dced265b9cfc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/45026c8383187ad1dcb14fbfec77dced265b9cfc", + "reference": "45026c8383187ad1dcb14fbfec77dced265b9cfc", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "php": "^5.6 || ^7.0", + "phpunit/php-text-template": "^1.2", + "sebastian/exporter": "^1.2 || ^2.0" + }, + "conflict": { + "phpunit/phpunit": "<5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.4" + }, + "suggest": { + "ext-soap": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Mock Object library for PHPUnit", + "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", + "keywords": [ + "mock", + "xunit" + ], + "time": "2016-11-19T09:07:46+00:00" + }, + { + "name": "psr/http-message", + "version": "1.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "85d63699f0dbedb190bbd4b0d2b9dc707ea4c298" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/85d63699f0dbedb190bbd4b0d2b9dc707ea4c298", + "reference": "85d63699f0dbedb190bbd4b0d2b9dc707ea4c298", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "time": "2015-05-04T20:22:00+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "c36f5e7cfce482fde5bf8d10d41a53591e0198fe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/c36f5e7cfce482fde5bf8d10d41a53591e0198fe", + "reference": "c36f5e7cfce482fde5bf8d10d41a53591e0198fe", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "phpunit/phpunit": "~5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "time": "2016-02-13T06:45:14+00:00" + }, + { + "name": "sebastian/comparator", + "version": "1.2.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "6a1ed12e8b2409076ab22e3897126211ff8b1f7f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/6a1ed12e8b2409076ab22e3897126211ff8b1f7f", + "reference": "6a1ed12e8b2409076ab22e3897126211ff8b1f7f", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "sebastian/diff": "~1.2", + "sebastian/exporter": "~1.2 || ~2.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "http://www.github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "time": "2016-11-19T09:18:40+00:00" + }, + { + "name": "sebastian/diff", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "5843509fed39dee4b356a306401e9dd1a931fec7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/5843509fed39dee4b356a306401e9dd1a931fec7", + "reference": "5843509fed39dee4b356a306401e9dd1a931fec7", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Diff implementation", + "homepage": "http://www.github.com/sebastianbergmann/diff", + "keywords": [ + "diff" + ], + "time": "2014-08-15T10:29:00+00:00" + }, + { + "name": "sebastian/environment", + "version": "1.3.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "22aa49baa48886f40b060e061a7967436f44a249" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/22aa49baa48886f40b060e061a7967436f44a249", + "reference": "22aa49baa48886f40b060e061a7967436f44a249", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "time": "2016-02-26T11:40:57+00:00" + }, + { + "name": "sebastian/exporter", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4", + "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "sebastian/recursion-context": "~2.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "http://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "time": "2016-11-19T08:54:04+00:00" + }, + { + "name": "sebastian/global-state", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "c7428acdb62ece0a45e6306f1ae85e1c05b09c01" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/c7428acdb62ece0a45e6306f1ae85e1c05b09c01", + "reference": "c7428acdb62ece0a45e6306f1ae85e1c05b09c01", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "time": "2014-10-06T09:23:50+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "96f8a3f257b69e8128ad74d3a7fd464bcbaa3b35" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/96f8a3f257b69e8128ad74d3a7fd464bcbaa3b35", + "reference": "96f8a3f257b69e8128ad74d3a7fd464bcbaa3b35", + "shasum": "" + }, + "require": { + "php": ">=5.6", + "sebastian/recursion-context": "~2.0" + }, + "require-dev": { + "phpunit/phpunit": "~5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "time": "2016-11-19T07:35:10+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/2c3ba150cbec723aa057506e73a8d33bdb286c9a", + "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "time": "2016-11-19T07:33:16+00:00" + }, + { + "name": "sebastian/resource-operations", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "shasum": "" + }, + "require": { + "php": ">=5.6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides a list of PHP built-in functions that operate on resources", + "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "time": "2015-07-28T20:34:47+00:00" + }, + { + "name": "sebastian/version", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "16b021aed448b654ae05846e394e057e9a6f04cb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/16b021aed448b654ae05846e394e057e9a6f04cb", + "reference": "16b021aed448b654ae05846e394e057e9a6f04cb", + "shasum": "" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "time": "2013-01-05T14:27:32+00:00" + }, + { + "name": "symfony/yaml", + "version": "v2.1.0", + "target-dir": "Symfony/Component/Yaml", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "f18e004fc975707bb4695df1dbbe9b0d8c8b7715" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/f18e004fc975707bb4695df1dbbe9b0d8c8b7715", + "reference": "f18e004fc975707bb4695df1dbbe9b0d8c8b7715", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } + }, + "autoload": { + "psr-0": { + "Symfony\\Component\\Yaml": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Symfony Yaml Component", + "homepage": "http://symfony.com", + "time": "2012-08-22T13:48:41+00:00" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": "^5.6 || ^7.0" + }, + "platform-dev": [] +} diff --git a/common/cron.php b/common/cron.php index 77d9d8f..9cc56a6 100644 --- a/common/cron.php +++ b/common/cron.php @@ -1,9 +1,13 @@ loadOpml(dirname(__FILE__).'/custom/people.opml')) { +if (0 < $Planet->loadOpml(__DIR__.'/custom/people.opml')) { $Planet->download(1.0); } -var_dump($Planet->errors); +if ($conf['debug'] === true) { + foreach ($Planet->errors as $error) { + echo $error->toString() . "\n"; + } +} \ No newline at end of file diff --git a/common/custom/img/moonmoon.png b/common/custom/img/moonmoon.png new file mode 100644 index 0000000..10f9736 Binary files /dev/null and b/common/custom/img/moonmoon.png differ diff --git a/common/custom/img/moonmoon@128w.png b/common/custom/img/moonmoon@128w.png new file mode 100644 index 0000000..2a164aa Binary files /dev/null and b/common/custom/img/moonmoon@128w.png differ diff --git a/common/custom/img/moonmoon@256w.png b/common/custom/img/moonmoon@256w.png new file mode 100644 index 0000000..b52c4bb Binary files /dev/null and b/common/custom/img/moonmoon@256w.png differ diff --git a/common/custom/style/default.css b/common/custom/style/default.css index de813ac..12268ef 100644 --- a/common/custom/style/default.css +++ b/common/custom/style/default.css @@ -1,128 +1,158 @@ -html{ +@viewport { + width: device-width; + initial-scale: 1.0; +} + +html { font-family: "Lucida Grande", "Segoe UI", sans-serif; color: #111; background: #EEE; font-size: 62.5%; } -body{ +body { margin: 0; padding: 0; font-size: 1.3em; line-height: 1.5em; } -a{ +a { color: #669; } -a:visited{ +a:visited { color: #444; } -a:hover{ +a:hover { color: #000; } -a img{ +a img { border: none; } -pre, code{ +pre, code { max-height: 100%; width: 100%; font-size: 1.2em; overflow: auto; } -h1, h2{ +h1, h2 { font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; } -h2{ +h2 { margin: 0; } #page { - width: 890px; - margin: 0 auto; + margin: 0 5em; } /* Header *******************************************************************************/ + #top { color: #FFF; padding: 10px 30px; } - h1 a, - h1 a:visited { - color: #665; - text-decoration: none; - } - h1 a:hover { - color: #444; - } + +h1 a, h1 a:visited { + color: #665; + text-decoration: none; +} + +h1 a:hover { + color: #444; +} /* Content *******************************************************************************/ + #content { - width: 590px; + width: 75%; float: left; } +#content img { + max-width: 100%; + height: auto; +} + /* Sidebar *******************************************************************************/ + #sidebar { - width: 300px; + width: 18%; float: left; } - #sidebar div { - padding: 1em 30px; - } - #sidebar h2 { - color: #665; - } - #sidebar ul { - list-style: none; - padding: 0; - margin: 1em 0; - } - + +#sidebar div { + padding: 1em 30px; +} + +#sidebar h2 { + color: #665; +} + +#sidebar ul { + list-style: none; + padding: 0; + margin: 1em 0; +} + /* Article *******************************************************************************/ -.article{ + +.article { margin-bottom: 2em; padding: 30px; background: #FFF; border: 1px solid #DDD; + overflow: hidden; } - .article-title, - .article-title a{ - color: #111; - text-decoration: none; - } +.article-title, .article-title a { + color: #111; + text-decoration: none; +} - .article-info{ - margin: 0 0 1em 0; - color: #999; - } - - .article-content { - font-family: Georgia, serif; - } +.article-info { + margin: 0 0 1em 0; + color: #999; +} - .article img{ - max-width: 440px; - } +.article-content { + font-family: Georgia, serif; +} - .article .collapsed{ - display: none; - } +.article img { + max-width: 440px; +} + +.article .collapsed { + display: none; +} /* Footer *******************************************************************************/ + #footer { clear: both; padding: 0 30px; +} + +@media screen and (max-width: 1023px) { + #page { + margin: 0px; + display: flex; + flex-direction: column; + } + #content, #sidebar { + float: none; + width: 100%; + } } \ No newline at end of file diff --git a/common/custom/views/archive/footer.tpl.php b/common/custom/views/archive/footer.tpl.php index bfc0210..c9c84b1 100755 --- a/common/custom/views/archive/footer.tpl.php +++ b/common/custom/views/archive/footer.tpl.php @@ -1,3 +1,3 @@ diff --git a/common/custom/views/archive/index.tpl.php b/common/custom/views/archive/index.tpl.php index 2bb8f36..16bc6ab 100755 --- a/common/custom/views/archive/index.tpl.php +++ b/common/custom/views/archive/index.tpl.php @@ -29,12 +29,12 @@ header('Content-type: text/html; charset=UTF-8'); <?php echo $PlanetConfig->getName(); ?> - +
- +
@@ -106,9 +106,9 @@ header('Content-type: text/html; charset=UTF-8');
- + - +
diff --git a/common/custom/views/archive/sidebar.tpl.php b/common/custom/views/archive/sidebar.tpl.php index e21f377..7a5d080 100755 --- a/common/custom/views/archive/sidebar.tpl.php +++ b/common/custom/views/archive/sidebar.tpl.php @@ -1,5 +1,5 @@ getPeople(); +$all_people = $Planet->getPeople(); usort($all_people, array('PlanetFeed', 'compare')); ?>