diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5aa30a2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/.buildpath +/.project +/.settings diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..26dcd2a --- /dev/null +++ b/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2013, The Web Builders Group Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, this + list of conditions and the following disclaimer in the documentation and/or + other materials provided with the distribution. + + Neither the name of The Web Builders Group Inc nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..d727778 --- /dev/null +++ b/README.md @@ -0,0 +1,43 @@ +Packagist Short Code +================= +Add a short code for adding a Packagist installs button with a count to a HTMLText field. + +## Maintainer Contact +* Ed Chipman ([UndefinedOffset](https://github.com/UndefinedOffset)) + +## Requirements +* SilverStripe CMS 3.x + + +## Installation +* Download the module from here https://github.com/webbuilders-group/silverstripe-packagistshortcode/archive/master.zip +* Extract the downloaded archive into your site root so that the destination folder is called githubshortcode, opening the extracted folder should contain _config.php in the root along with other files/folders +* Run dev/build?flush=all to regenerate the manifest + + +## Usage +Usage is pretty straight forward to add a packagist downloads button you simply add the following: +``` +[packagist package="package owner/package name"] +``` + +Optionally you may add mode="monthly" or button="daily" (defaults to total) to show the download count for the given period. +``` +[packagist package="package owner/package name" mode="monthly"] + +``` + +In 3.1 the short codes above will work as included however the updated syntax for the short code would be (of course layout and button are not required): +``` +[packagist,package="package owner/package name",mode="monthly"] +``` + + +#### Configuration Options +There are a few configuration options available to you: + +```yml +PackagistShortCode: + CacheTime: 86400 #Cache time in seconds (default is 1 day, remember the GitHub api is rate limited) + UseShortHandNumbers: true #Use short hand numbers i.e 5.6K or not +``` diff --git a/_config.php b/_config.php new file mode 100644 index 0000000..3f9c716 --- /dev/null +++ b/_config.php @@ -0,0 +1,6 @@ +register('packagist', array('PackagistShortCode', 'parse')); +?> \ No newline at end of file diff --git a/_config/config.yml b/_config/config.yml new file mode 100644 index 0000000..46f53c4 --- /dev/null +++ b/_config/config.yml @@ -0,0 +1,6 @@ +--- +Name: packagistbutton +--- +PackagistShortCode: + CacheTime: 86400 #Cache time in seconds + UseShortHandNumbers: true #Use short hand numbers i.e 5.6K or not \ No newline at end of file diff --git a/code/PackagistShortCode.php b/code/PackagistShortCode.php new file mode 100644 index 0000000..def229e --- /dev/null +++ b/code/PackagistShortCode.php @@ -0,0 +1,109 @@ +Packagist package undefined
'; + } + + //Get Config + $config=Config::inst()->forClass('PackagistShortCode'); + + + $obj=new ViewableData(); + + //Add the Respository Setting + $obj->Package=$arguments['package']; + + //Add the button config + if(array_key_exists('mode', $arguments) && ($arguments['mode']=='total' || $arguments['mode']=='monthly' || $arguments['mode']=='daily')) { + $obj->DisplayMode=$arguments['mode']; + }else { + $obj->DisplayMode='total'; + } + + //Retrieve Stats + SS_Cache::set_cache_lifetime('PackagistShortCode', $config->CacheTime); + + $cacheKey=md5('packagistshortcode_'.$arguments['package']); + $cache=SS_Cache::factory('PackagistShortCode'); + $cachedData=$cache->load($cacheKey); + if($cachedData==null) { + $response=self::getFromAPI($arguments['package']); + + //Verify a 200, if not say the repo errored out and cache false + if(empty($response) || $response===false || !property_exists($response, 'package')) { + $cachedData=array('total'=>'N/A', 'monthly'=>'N/A', 'daily'=>'N/A'); + }else { + if($config->UseShortHandNumbers==true) { + $totalDownloads=self::shortHandNumber($response->package->downloads->total); + $monthlyDownloads=self::shortHandNumber($response->package->downloads->monthly); + $dailyDownloads=self::shortHandNumber($response->package->downloads->daily); + }else { + $totalDownloads=number_format($response->package->downloads->total); + $monthlyDownloads=number_format($response->package->downloads->monthly); + $dailyDownloads=number_format($response->package->downloads->daily); + } + + $cachedData=array('total'=>$totalDownloads, 'monthly'=>$monthlyDownloads, 'daily'=>$dailyDownloads); + } + + //Cache response to file system + $cache->save(serialize($cachedData), $cacheKey); + }else { + $cachedData=unserialize($cachedData); + } + + + $obj->TotalDownloads=$cachedData['total']; + $obj->MonthlyDownloads=$cachedData['monthly']; + $obj->DailyDownloads=$cachedData['daily']; + + + //Init ss viewer and render + Requirements::css(PACKAGISTSHORTCODE_BASE.'/css/PackagistButton.css'); + + $ssViewer=new SSViewer('PackagistButton'); + return $ssViewer->process($obj); + } + + /** + * Loads the data from the github api + * @param {string} $url URL to load + * @return {stdObject} Returns the JSON Response from the GitHub API + * + * @see http://developer.github.com/v3/repos/#get + */ + final protected static function getFromAPI($repo) { + if(function_exists('curl_init') && $ch=curl_init()) { + curl_setopt($ch, CURLOPT_URL, 'https://packagist.org/packages/'.$repo.'.json'); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); + + + $contents=json_decode(curl_exec($ch)); + curl_close($ch); + + return $contents; + }else { + user_error('CURL is not available', E_USER_ERROR); + } + } + + /** + * Gets the short hand of the given number so 1000 becomes 1k, 2000 becomes 2k, and 1000000 becomes 1m etc + * @param {int} $number Number to convert + * @return {string} Short hand of the given number + */ + protected static function shortHandNumber($number) { + if($number>=1000000000) { + return round($number/1000000000, 1).'B'; + }else if($number>=1000000) { + return round($number/1000000, 1).'M'; + }else if($number>=1000) { + return round($number/1000, 1).'K'; + } + + return $number; + } +} +?> \ No newline at end of file diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..367a3ef --- /dev/null +++ b/composer.json @@ -0,0 +1,23 @@ +{ + "name": "webbuilders-group/silverstripe-packagistshortcode", + "description": "Add a short code for adding a Packagist installs button with a count to a HTMLText field.", + "type": "silverstripe-module", + "keywords": ["silverstripe", "packagist", "shortcode"], + "license": "BSD-3-Clause", + "authors": [ + { + "name": "Ed Chipman", + "homepage": "http://webbuildersgroup.com", + "role": "Developer" + } + ], + + "require": + { + "silverstripe/framework": "3.*", + "composer/installers": "*" + }, + "support": { + "issues": "https://github.com/webbuilders-group/silverstripe-packagistshortcode/issues" + } +} diff --git a/css/PackagistButton.css b/css/PackagistButton.css new file mode 100644 index 0000000..08536d4 --- /dev/null +++ b/css/PackagistButton.css @@ -0,0 +1,98 @@ +.packagistButtonGroup .packagistButton { + clear: both; + + margin: 10px 0 20px 0; +} + +.packagistButtonGroup.stacked .packagistButton { + display: block; +} + +.packagistButtonGroup.stacked .packagistButton + .packagistButton { + margin-top: -10px; +} + +.packagistButtonGroup.inline .packagistButton + .packagistButton { + margin-left: 4ex; +} + +.packagistButtonGroup .packagistButton a { + background: url(./../images/packagist-button.png) no-repeat; + + display: inline-block; + + width: 170px; + height: 26px; + + vertical-align: middle; +} + +.packagistButtonGroup a.packagistDownloadsButton:hover, .packagistButtonGroup a.packagistDownloadsButton:active { + background-position: 0 -26px; +} + +.packagistButtonGroup .packagistButton span.count { + background-color: #FAFAFA; + + position: relative; + + font-family: Arial, sans-serif; + font-size: 11px; + color: #666666; + + text-decoration: none; + text-shadow: 0 1px 0 #FFFFFF; + + line-height: 15px; + + white-space: nowrap; + + border: 1px solid #DDDDDD; + + margin-left: 8px; + padding: 6px 7px 5px; + + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} + +.packagistButtonGroup .packagistButton span.count:after { + display: block; + + position: absolute; + top: 50%; + right: 100%; + + content: ""; + + border-width: 6px; + border-style: solid; + border-color: transparent #FAFAFA transparent transparent; + + width: 0; + height: 0; + + margin-right: -1px; + margin-top: -6px; +} + +.packagistButtonGroup .packagistButton span.count:before { + display: block; + + position: absolute; + top: 50%; + right: 100%; + + content: ""; + + border-width: 6px; + border-style: solid; + border-color: transparent #D4D4D4 transparent transparent; + + width: 0; + height: 0; + + margin-right: 0; + margin-top: -6px; +} \ No newline at end of file diff --git a/images/packagist-button.png b/images/packagist-button.png new file mode 100644 index 0000000..b6cc080 Binary files /dev/null and b/images/packagist-button.png differ diff --git a/templates/Includes/PackagistButton.ss b/templates/Includes/PackagistButton.ss new file mode 100644 index 0000000..cc5cca4 --- /dev/null +++ b/templates/Includes/PackagistButton.ss @@ -0,0 +1,14 @@ ++ + + + <% if $DisplayMode=='monthly' %> + $MonthlyDownloads + <% else_if $DisplayMode=='daily' %> + $DailyDownloads + <% else %> + $TotalDownloads + <% end_if %> + + +
\ No newline at end of file