Merge remote-tracking branch 'site/1.1' into 1.1

This commit is contained in:
merdan 2021-06-17 15:15:04 +05:00
commit 9cdbc9cbc6
165 changed files with 10249 additions and 104 deletions

View File

@ -41,3 +41,22 @@ scopes:
# SQL Conditions
conditions: created_at >= ':after' AND created_at <= ':before'
language:
# Filter name
label: Language
# Model Class name
modelClass: RainLab\Blog\Models\Post
# Model attribute to display for the name
nameFrom: locale
# Apply query scope
scope: FilterLocale
# options
options:
ru: RU
en: EN

View File

@ -400,6 +400,21 @@ class Post extends Model
});
}
public function scopeFilterLocale($query, array $types) {
foreach ($types as $type) {
switch ($type) {
case 'en':
return $query->where('locale', 'en');
break;
case 'ru':
return $query->where('locale', 'ru');
break;
}
}
}
//
// Summary / Excerpt
//

View File

@ -0,0 +1,19 @@
# MIT license
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,129 @@
<?php namespace ToughDeveloper\ImageResizer;
use System\Classes\PluginBase;
use ToughDeveloper\ImageResizer\Classes\Image;
use Validator;
/**
* ImageResizer Plugin Information File
*/
class Plugin extends PluginBase
{
/**
* Returns information about this plugin.
*
* @return array
*/
public function pluginDetails()
{
return [
'name' => 'toughdeveloper.imageresizer::lang.plugin.name',
'description' => 'toughdeveloper.imageresizer::lang.plugin.description',
'author' => 'Tough Developer',
'icon' => 'icon-picture-o',
'homepage' => 'https://github.com/toughdeveloper/oc-imageresizer-plugin'
];
}
/**
* Registers any back-end permissions used by this plugin.
*
* @return array
*/
public function registerPermissions()
{
return [
'toughdeveloper.imageresizer.access_settings' => [
'tab' => 'toughdeveloper.imageresizer::lang.permission.tab',
'label' => 'toughdeveloper.imageresizer::lang.permission.label'
]
];
}
public function boot(){
Validator::extend('valid_tinypng_key', function($attribute, $value, $parameters) {
try {
\Tinify\setKey($value);
\Tinify\validate();
} catch(\Tinify\Exception $e) {
return false;
}
return true;
});
}
public function registerMarkupTags()
{
return [
'filters' => [
'resize' => function($file_path, $width = false, $height = false, $options = []) {
$image = new Image($file_path);
return $image->resize($width, $height, $options);
},
'imageWidth' => function($image) {
if (!$image instanceOf Image) {
$image = new Image($image);
}
return getimagesize($image->getCachedImagePath())[0];
},
'imageHeight' => function($image) {
if (!$image instanceOf Image) {
$image = new Image($image);
}
return getimagesize($image->getCachedImagePath())[1];
}
]
];
}
public function registerSettings()
{
return [
'settings' => [
'label' => 'toughdeveloper.imageresizer::lang.settings.label',
'icon' => 'icon-picture-o',
'description' => 'toughdeveloper.imageresizer::lang.settings.description',
'class' => 'ToughDeveloper\ImageResizer\Models\Settings',
'order' => 0,
'permissions' => ['toughdeveloper.imageresizer.access_settings']
]
];
}
public function registerListColumnTypes()
{
return [
'thumb' => [$this, 'evalThumbListColumn'],
];
}
public function evalThumbListColumn($value, $column, $record)
{
$config = $column->config;
// Get config options with defaults
$width = isset($config['width']) ? $config['width'] : 50;
$height = isset($config['height']) ? $config['height'] : 50;
$options = isset($config['options']) ? $config['options'] : [];
// attachMany relation?
if (isset($record->attachMany[$column->columnName]))
{
$file = $value->first();
}
// attachOne relation?
else if (isset($record->attachOne[$column->columnName]))
{
$file = $value;
}
// Mediafinder
else
{
$file = storage_path() . '/app/media' . $value;
}
$image = new Image($file);
return $image->resize($width, $height, $options)->render();
}
}

View File

@ -0,0 +1,113 @@
# Image Resizer
- [Introduction](#introduction)
- [Available filters](#filters)
- [Using a string](#string)
- [Using a variable](#variable)
- [resize()](#resize)
- [imageWidth() - imageHeight()](#imageDimensions)
- [Image Compression](#compression)
<a name="introduction"></a>
## Introduction
Resizes an image to the required dimensions. It accepts a string with a file path to the image or a `October\Rain\Database\Attach\File` object (you will have one of these if you have used the attachOne or AttachMany relationship)
Please note, the not found image can be overwritten via the settings in the admin area.
<a name="filters"></a>
## Available filters
[`resize(int $width [, int $height , array $options])`](#resize), [`imageWidth()`](#imageDimensions), [`imageHeight()`](#imageDimensions)
<a name="string"></a>
### Using a string
Please note, if the filter alters the URL, you must apply resize afterwards
```
{{ 'assets/graphics/background.jpg' | theme | resize(500,500) }}
```
<a name="variable"></a>
### Using a variable
```
{{ property.image | resize(500) }}
```
<a name="resize"></a>
## resize(int $width [, int $height , array $options])
Resize an image according to the given params. If `$width` or `$height` is `0`, that value is calculated using original image ratio
### Options
Key | Description | Default | Options
--- | --- | --- | ---
mode | How the image should be fitted to dimensions | auto | exact, portrait, landscape, auto, fit or crop
offset | Offset the resized image | [0,0] | [int, int]
extension | The extension on the image to return | auto | auto, jpg, jpeg, gif, png
quality | The quality of compression _*requires cache clear_ | 95 | 0-100
sharpen | Sharpen the image across a scale of 0 - 100 _*requires cache clear_ | 0 | 0-100
compress | Whether the image should be compressed or not. Only takes effect when TinyPng compression is enabled. | true | true,false
### Usage in template
```
{{ property.image | resize(500, false, { mode: 'crop', quality: '80', extension: 'png' }) }}
```
### Usage in PHP
The image resizer can also be used easily in PHP, as follows:
```
use ToughDeveloper\ImageResizer\Classes\Image;
$image = new Image('/path/to/image.jpg');
$image->resize(150, 200, [ 'mode' => 'crop' ]);
```
### Usage in Backend List
The image resizer can also be used on backend lists with the type of `thumb`, e.g.
```
image:
label: Image
type: thumb
```
This works with:
- AttachMany (uses first image) [Docs](https://octobercms.com/docs/backend/forms#widget-fileupload)
- AttachOne [Docs](https://octobercms.com/docs/backend/forms#widget-fileupload)
- Mediafinder [Docs](https://octobercms.com/docs/backend/forms#widget-mediafinder)
You can also optionally pass width (default 50), height (default 50) and options as follows:
```
image:
label: Image
type: thumb
width: 75
height: 100
options:
mode: crop
```
<a name="imageDimensions"></a>
## imageWidth() - imageHeight()
Return current image width/height - useful if you need to know the size of an image resized only by one side.
```
{{ '/path/to/image.jpg' | resize(250) | imageHeight() }}
```
<a name="compression"></a>
## Image Compression via TinyPNG
The plugin integrates with the TinyPNG API to provide image compression. A developer API key is required, to obtain one visit https://tinypng.com/developers. Once obtained, enter it in the Image Resizer Settings area of October CMS backend.
TinyPNG offer 500 free compression per month, the plugin automatically caches resized images to save credits, an option to not compress certain images is also available.
If you are focussed on pagespeed, it is recommended to set your image quality at 70-80 to obtain the lowest filesize whilst still retaining high quality images.

Binary file not shown.

After

Width:  |  Height:  |  Size: 773 KiB

View File

@ -0,0 +1,326 @@
<?php namespace ToughDeveloper\ImageResizer\Classes;
use ToughDeveloper\ImageResizer\Models\Settings;
use October\Rain\Database\Attach\File;
use Tinify\Tinify;
use Tinify\Source;
class Image
{
/**
* File path of image
*/
protected $filePath;
/**
* Image Resizer Settings
*/
protected $settings;
/**
* File Object
*/
protected $file;
/**
* Options Array
*/
protected $options;
/**
* Thumb filename
*/
protected $thumbFilename;
public function __construct($filePath = false)
{
// Settings are needed often, so offset to variable
$this->settings = Settings::instance();
// Create a new file object
$this->file = new File;
if ($filePath instanceof File) {
$this->filePath = $filePath->getLocalPath();
return;
}
$this->filePath = (file_exists($filePath))
? $filePath
: $this->parseFileName($filePath);
}
/**
* Resizes an Image
*
* @param integer $width The target width
* @param integer $height The target height
* @param array $options The options
*
* @return string
*/
public function resize($width = false, $height = false, $options = [])
{
// Parse the default settings
$this->options = $this->parseDefaultSettings($options);
// Not a file? Display the not found image
if (!is_file($this->filePath)) {
return $this->notFoundImage($width, $height);
}
// If extension is auto, set the actual extension
if (strtolower($this->options['extension']) == 'auto') {
$this->options['extension'] = pathinfo($this->filePath)['extension'];
}
// Set a disk name, this enables caching
$this->file->disk_name = $this->diskName();
// Set the thumbfilename to save passing variables to many functions
$this->thumbFilename = $this->getThumbFilename($width, $height);
// If the image is cached, don't try resized it.
if (! $this->isImageCached()) {
// Set the file to be created from another file
$this->file->fromFile($this->filePath);
// Resize it
$thumb = $this->file->getThumb($width, $height, $this->options);
// Not a gif file? Compress with tinyPNG
if ($this->isCompressionEnabled()) {
$this->compressWithTinyPng();
}
// Touch the cached image with the original mtime to align them
touch($this->getCachedImagePath(), filemtime($this->filePath));
$this->deleteTempFile();
}
// Return the URL
return $this;
}
/**
* Gets the path for the thumbnail
* @return string
*/
public function getCachedImagePath($public = false)
{
$filePath = $this->file->getStorageDirectory() . $this->getPartitionDirectory() . $this->thumbFilename;
if ($public === true) {
return url('/storage/app/' . $filePath);
}
return storage_path('app/' . $filePath);
}
protected function deleteTempFile()
{
$path = storage_path('app/' . $this->file->getStorageDirectory() . $this->getPartitionDirectory() . $this->file->disk_name);
if (file_exists($path)) {
unlink($path);
}
}
/**
* Parse the file name to get a relative path for the file
* This is mostly required for scenarios where a twig filter, e.g. theme has been applied.
* @return string
*/
protected function parseFileName($filePath)
{
$path = urldecode(parse_url($filePath, PHP_URL_PATH));
// Create array of commonly used folders
// These will be used to try capture the actual file path to an image without the sub-directory path
$folders = [
config('cms.themesPath'),
config('cms.pluginsPath'),
config('cms.storage.uploads.path'),
config('cms.storage.media.path')
];
foreach($folders as $folder)
{
if (str_contains($path, $folder))
{
$paths = explode($folder, $path, 2);
return base_path($folder . end($paths));
}
}
return base_path($path);
}
/**
* Works out the default settings
* @return string
*/
protected function parseDefaultSettings($options = [])
{
if (!isset($options['mode']) && $this->settings->default_mode) {
$options['mode'] = $this->settings->default_mode;
}
if (!isset($options['offset']) && is_int($this->settings->default_offset_x) && is_int($this->settings->default_offset_y)) {
$options['offset'] = [$this->settings->default_offset_x, $this->settings->default_offset_y];
}
if (!isset($options['extension']) && $this->settings->default_extension) {
$options['extension'] = $this->settings->default_extension;
}
if (!isset($options['quality']) && is_int($this->settings->default_quality)) {
$options['quality'] = $this->settings->default_quality;
}
if (!isset($options['sharpen']) && is_int($this->settings->default_sharpen)) {
$options['sharpen'] = $this->settings->default_sharpen;
}
if (!isset($options['compress'])) {
$options['compress'] = true;
}
return $options;
}
/**
* Creates a unique disk name for an image
* @return string
*/
protected function diskName()
{
$diskName = $this->filePath;
// Ensures a unique filepath when tinypng compression is enabled
if ($this->isCompressionEnabled()) {
$diskName .= 'tinypng';
}
return md5($diskName);
}
/**
* Serves a not found image
* @return string
*/
protected function notFoundImage($width, $height)
{
// Have we got a custom not found image? If so, serve this.
if ($this->settings->not_found_image) {
$imagePath = base_path() . config('cms.storage.media.path') . $this->settings->not_found_image;
}
// If we do not have an existing custom not found image, use the default from this plugin
if (!isset($imagePath) || !file_exists($imagePath)) {
$imagePath = plugins_path('toughdeveloper/imageresizer/assets/default-not-found.jpg');
}
// Create a new Image object to resize
$file = new Self($imagePath);
// Return in the specified dimensions
return $file->resize($width, $height, [
'mode' => 'crop'
]);
}
/**
* Compresses a png image using tinyPNG
* @return string
*/
protected function compressWithTinyPng()
{
try {
Tinify::setKey($this->settings->tinypng_developer_key);
$filePath = $this->getCachedImagePath();
$source = Source::fromFile($filePath);
$source->toFile($filePath);
}
catch (\Exception $e) {
// Log error - may help debug
\Log::error('Tiny PNG compress failed', [
'message' => $e->getMessage(),
'code' => $e->getCode()
]);
}
}
/**
* Checks if the requested resize/compressed image is already cached.
* Removes the cached image if the original image has a different mtime.
*
* @return bool
*/
protected function isImageCached()
{
// if there is no cached image return false
if (!is_file($cached_img = $this->getCachedImagePath())) {
return false;
}
// if cached image mtime match, the image is already cached
if (filemtime($this->filePath) === filemtime($cached_img)) {
return true;
}
// delete older cached file
unlink($cached_img);
// generate new cache file
return false;
}
/**
* Checks if image compression is enabled for this image.
* @return bool
*/
protected function isCompressionEnabled()
{
return ($this->options['extension'] != 'gif' && $this->settings->enable_tinypng && $this->options['compress']);
}
/**
* Generates a partition for the file.
* return /ABC/DE1/234 for an name of ABCDE1234.
* @param Attachment $attachment
* @param string $styleName
* @return mixed
*/
protected function getPartitionDirectory()
{
return implode('/', array_slice(str_split($this->diskName(), 3), 0, 3)) . '/';
}
/**
* Generates a thumbnail filename.
* @return string
*/
protected function getThumbFilename($width, $height)
{
$width = (integer) $width;
$height = (integer) $height;
return 'thumb__' . $width . '_' . $height . '_' . $this->options['offset'][0] . '_' . $this->options['offset'][1] . '_' . $this->options['mode'] . '.' . $this->options['extension'];
}
/**
* Render an image tag
* @return string
*/
public function render()
{
return '<img src="' . $this . '" />';
}
/**
* Magic method to return the file path
* @return string
*/
public function __toString()
{
return $this->getCachedImagePath(true);
}
}

View File

@ -0,0 +1,8 @@
{
"name": "toughdeveloper/imageresizer-plugin",
"type": "october-plugin",
"description": "None",
"require": {
"composer/installers": "~1.0"
}
}

View File

@ -0,0 +1,46 @@
<?php
return [
'plugin' => [
'name' => 'Bildskalierung',
'description' => 'Stellt Twig-Filter zum Skalieren von Bildern bereit.'
],
'settings' => [
'label' => 'Bildskalierung Einstellungen',
'description' => 'Einstellungen der Bildskalierung verwalten',
'tab_default' => 'Vorgaben',
'tab_advanced' => 'Erweitert',
'not_found_image_label' => 'Nicht gefunden Bild',
'not_found_image_comment' => 'Zeigt ein anpassbares Bild an, sollte das Bild nicht existieren.',
'default_mode_label' => 'Standard Modus',
'default_mode_comment' => 'Wie soll das Bild skaliert werden.',
'default_offset_x_label' => 'Standard Abstand X',
'default_offset_x_comment' => 'Setzt einen horizontalen Abstand.',
'default_offset_y_label' => 'Standard Abstand Y',
'default_offset_y_comment' => 'Setzt einen vertikalen Abstand.',
'default_extension_label' => 'Standard Erweiterung',
'default_extension_comment' => 'Die Erweiterung des zurückgegebenen Bildes.',
'default_quality_label' => 'Standard Qualität',
'default_quality_comment' => 'Die Qualität der Komprimierung (erfordert das Leeren des Chaches).',
'default_sharpen_label' => 'Standard Schärfung',
'default_sharpen_comment' => 'Schärft das Bild von 0 - 100 (erfordert das Leeren des Chaches).',
'tinypng_hint' => 'Um einen Entwickler-Schlüssel für <a href="http://tinypng.com" target="_blank">TinyPNG</a> zu bekommen, bitte <a href="https://tinypng.com/developers" target="_blank">https://tinypng.com/developers</a> besuchen. Mit Angabe der E-Mail Addresse wird ein Link zum Schlüssel gesendet. Die ersten 500 Bilder pro Monat sind gratis, komprimierte Bilder werden gespeichert um die Anfragen zu reduzieren. Für die meisten Seiten reicht dies aus. Es wird geraten dieses Feature nur so wenig wie möglich und nur Live zu benutzen.',
'enable_tinypng_label' => 'Komprimiere Bilder mit TinyPNG',
'enable_tinypng_comment' => 'Fügt die Möglichkeit hinzu Bilder mit der tinypng.com API zu komprimieren und so die Dateigröße zu minimieren',
'tinypng_developer_key_label' => 'Entwickler Schlüssel',
'tinypng_developer_key_comment' => 'Siehe oben für eine Anleitung zum Erhalt eines Schlüssels',
'auto' => 'Auto',
'mode_exact' => 'Exakt',
'mode_portrait' => 'Hochformat',
'mode_landscape' => 'Querformat',
'mode_crop' => 'Abschneiden',
'tinypng_invalid_key' => 'Der tinypng Schlüssel konnte nicht validiert werden, bitte überprüfen und erneut probieren.',
'tinypng_compressed_images' => 'Komprimierte Bilder',
'tinypng_remaining_compressions' => 'Verbleibende kostenlose Komprimierungen',
'tinypng_days_until_reset' => 'Tage bis zum Reset'
],
'permission' => [
'tab' => 'Bildskalierung',
'label' => 'Einstellungen verwalten'
]
];

View File

@ -0,0 +1,46 @@
<?php
return [
'plugin' => [
'name' => 'Image Resizer',
'description' => 'Provides Twig filter to resize images on the fly.'
],
'settings' => [
'label' => 'Image Resizer Settings',
'description' => 'Configure Image Resizer Settings',
'tab_default' => 'Defaults',
'tab_advanced' => 'Advanced',
'not_found_image_label' => 'Not Found Image',
'not_found_image_comment' => 'Displays a customizable image if the image doesn\'t exist.',
'default_mode_label' => 'Default mode',
'default_mode_comment' => 'How the image should be fitted to dimensions.',
'default_offset_x_label' => 'Default offset X',
'default_offset_x_comment' => 'Offset the resized image horizontally.',
'default_offset_y_label' => 'Default offset Y',
'default_offset_y_comment' => 'Offset the resized image vertically.',
'default_extension_label' => 'Default extension',
'default_extension_comment' => 'The extension on the image to return.',
'default_quality_label' => 'Default quality',
'default_quality_comment' => 'The quality of compression (requires cache clear).',
'default_sharpen_label' => 'Default sharpen',
'default_sharpen_comment' => 'Sharpen the image across a scale of 0 - 100 (requires cache clear).',
'tinypng_hint' => 'To obtain your developer key for <a href="http://tinypng.com" target="_blank">TinyPNG</a>, please visit <a href="https://tinypng.com/developers" target="_blank">https://tinypng.com/developers</a>. Enter your email address and a link to your developer key will be emailed across to you. The first 500 compressions a month are free, compressed images are cached to reduce the number of requests and for most sites this will suffice. It is recommended to keep the number of requests to a minimum, to only enable this setting on production servers.',
'enable_tinypng_label' => 'Compress images with TinyPNG',
'enable_tinypng_comment' => 'Adds the ability to run images through tinypng.com API to reduce filesize',
'tinypng_developer_key_label' => 'Developer Key',
'tinypng_developer_key_comment' => 'See above for details of how to obtain this',
'auto' => 'Auto',
'mode_exact' => 'Exact',
'mode_portrait' => 'Portrait',
'mode_landscape' => 'Landscape',
'mode_crop' => 'Crop',
'tinypng_invalid_key' => 'The tinypng key entered could not be validated, please check the key and try again.',
'tinypng_compressed_images' => 'Compressed Images',
'tinypng_remaining_compressions' => 'Remaining Free Compressions',
'tinypng_days_until_reset' => 'Days until reset'
],
'permission' => [
'tab' => 'Image Resizer',
'label' => 'Manage Settings'
]
];

View File

@ -0,0 +1,46 @@
<?php
return [
'plugin' => [
'name' => 'Image Resizer',
'description' => 'Fournit un filtre Twig pour redimensionner les images.'
],
'settings' => [
'label' => 'Paramètres Image Resizer',
'description' => 'Configurer les paramètres d\'Image Resizer',
'tab_default' => 'Réglages généraux',
'tab_advanced' => 'Réglages avancés',
'not_found_image_label' => 'Image introuvable',
'not_found_image_comment' => 'Affiche une image personnalisée si l\'image n\'existe pas.',
'default_mode_label' => 'Mode par défaut',
'default_mode_comment' => 'Comment l\'image doit être adaptée aux dimensions.',
'default_offset_x_label' => 'Décalage par défaut X',
'default_offset_x_comment' => 'Décalez l\'image redimensionnée horizontalement.',
'default_offset_y_label' => 'Décalage par défaut Y',
'default_offset_y_comment' => 'Décalez l\'image redimensionnée verticalement',
'default_extension_label' => 'Extension par défaut',
'default_extension_comment' => 'L\'extension de l\'image affiché.',
'default_quality_label' => 'Qualité par défaut',
'default_quality_comment' => 'La qualité de la compression (nécessite la suppression du cache).',
'default_sharpen_label' => 'Accentuage par défaut',
'default_sharpen_comment' => 'Accentuez l\'image sur une échelle de 0 à 100 (nécessite la suppression du cache).',
'tinypng_hint' => 'Pour obtenir votre clé de développeur pour <a href="https://tinypng.com" target="_blank">TinyPNG</a>, consultez la page <a href="https://tinypng.com/developers" target="_blank">https://tinypng.com/developers</a>. Entrez votre adresse e-mail et un lien vers votre clé développeur vous sera envoyé par courriel. Les 500 premières compressions par mois sont gratuites, les images compressées sont mises en cache afin de réduire le nombre de demandes. Cela suffira pour la plupart des sites. Il est recommandé de limiter le nombre de demandes au minimum afin d\'activer ce paramètre uniquement sur les serveurs de production.',
'enable_tinypng_label' => 'Compresser les images avec TinyPNG',
'enable_tinypng_comment' => 'Ajoute la possibilité de compresser des images via l\'API tinypng.com afin de réduire la taille du fichier.',
'tinypng_developer_key_label' => 'Clé de développeur',
'tinypng_developer_key_comment' => 'Voir ci-dessus pour savoir comment obtenir la clé.',
'auto' => 'Auto',
'mode_exact' => 'Exact',
'mode_portrait' => 'Portrait',
'mode_landscape' => 'Paysage',
'mode_crop' => 'Rogner',
'tinypng_invalid_key' => 'La clé TinyPNG saisie n\'a pas pu être validée. Veuillez vérifier la clé et réessayer.',
'tinypng_compressed_images' => 'Images compressées',
'tinypng_remaining_compressions' => 'Compressions gratuites restantes',
'tinypng_days_until_reset' => 'Jours jusqu\'à la réinitialisation'
],
'permission' => [
'tab' => 'Image Resizer',
'label' => 'Gérer les paramètres'
]
];

View File

@ -0,0 +1,46 @@
<?php
return [
'plugin' => [
'name' => 'Képméretezés',
'description' => 'Képek dinamikus átméretezése és módosítása.'
],
'settings' => [
'label' => 'Képméretezés',
'description' => 'Szolgáltatáshoz tartozó beállítások',
'tab_default' => 'Általános',
'tab_advanced' => 'Kiegészítők',
'not_found_image_label' => 'Helyettesítő kép',
'not_found_image_comment' => 'Ha nem létezik az adott kép, akkor ez a kép jelenik meg.',
'default_mode_label' => 'Alapértelmezett mód',
'default_mode_comment' => 'A kép arányának meghatározása.',
'default_offset_x_label' => 'Alapértelmezett X eltolás',
'default_offset_x_comment' => 'A kép vízszintes eltolásának mértéke képpontban.',
'default_offset_y_label' => 'Alapértelmezett Y eltolás',
'default_offset_y_comment' => 'A kép függőleges eltolásának mértéke képpontban.',
'default_extension_label' => 'Alapértelmezett kiterjesztés',
'default_extension_comment' => 'A kép kiterjesztésének fajtája.',
'default_quality_label' => 'Alapértelmezett minőség',
'default_quality_comment' => 'A kép minőségének mértéke. 0 és 100 közötti érték lehet.',
'default_sharpen_label' => 'Alapértelmezett élesítés',
'default_sharpen_comment' => 'A kép élesítésének mértéke. 0 és 100 közötti érték lehet.',
'tinypng_hint' => 'A <a href="http://tinypng.com" target="_blank">TinyPNG</a> használatához először regisztráljon a <a href="https://tinypng.com/developers" target="_blank">https://tinypng.com/developers</a> címen. Ezt követően e-mailben fog kapni egy linket, amin keresztül elérheti a személyes fejlesztői kulcsát. Az első 500 tömörítés ingyenes minden hónapban. Javasoljuk, hogy a havi keret túllépésének elkerülése érdekében, csak éles weboldalnál kapcsolja be a szolgáltatást.',
'enable_tinypng_label' => 'Képek tömörítése a TinyPNG segítségével',
'enable_tinypng_comment' => 'A png kiterjesztésű képek méretének csökkentése a szolgáltatással használatával.',
'tinypng_developer_key_label' => 'Fejlesztői kulcs',
'tinypng_developer_key_comment' => 'A részleteket a fenti leírásban találja.',
'auto' => 'Automatikus',
'mode_exact' => 'Pontos',
'mode_portrait' => 'Álló',
'mode_landscape' => 'Fekvő',
'mode_crop' => 'Levágott',
'tinypng_invalid_key' => 'A megadott tinypng kulcsot nem lehet érvényesíteni. Kérjük ellenőrizze és próbálja újra.',
'tinypng_compressed_images' => 'Tömörített képek',
'tinypng_remaining_compressions' => 'Fennmaradó kompresszió',
'tinypng_days_until_reset' => 'Napok törlésig'
],
'permission' => [
'tab' => 'Képméretezés',
'label' => 'Beállítások kezelése'
]
];

View File

@ -0,0 +1,46 @@
<?php
return [
'plugin' => [
'name' => 'Image Resizer',
'description' => '提供图片大小条这个的 Twig filter。'
],
'settings' => [
'label' => 'Image Resizer 设置',
'description' => '配置图片大小调节设置',
'tab_default' => '默认',
'tab_advanced' => '高级',
'not_found_image_label' => '未找到图片',
'not_found_image_comment' => '在图片不存在时展示一个自定义的图片。',
'default_mode_label' => '默认模式',
'default_mode_comment' => '图像应该如何与尺寸匹配。',
'default_offset_x_label' => '默认 X 轴偏移量',
'default_offset_x_comment' => '调整大小时垂直方向上的偏移量。',
'default_offset_y_label' => '默认 Y 轴偏移量',
'default_offset_y_comment' => '调整大小时垂直方向上的偏移量。',
'default_extension_label' => '默认扩展名',
'default_extension_comment' => '返回的图片的扩展名。',
'default_quality_label' => '默认质量',
'default_quality_comment' => '图片压缩质量(需要清空缓存)。',
'default_sharpen_label' => '默认锐化程度',
'default_sharpen_comment' => '在 0 - 100 范围内锐化图片(需要清空缓存)。',
'tinypng_hint' => '要申请自己的 <a href="http://tinypng.com" target="_blank">TinyPNG</a> 开发者 key, 请访问 <a href="https://tinypng.com/developers" target="_blank">https://tinypng.com/developers</a>。输入你的邮箱地址,一个你开发者 key 的链接将会通过邮件发送给你。每个月的前 500 次压缩免费,压缩后的图片会缓存下来,用以减少请求次数,这对于大部分网站已经足够了。建议尽量减少请求数量,仅在生产服务器上启用此设置。',
'enable_tinypng_label' => '使用 TinyPNG 压缩图片',
'enable_tinypng_comment' => '提供通过 tinypng.com API 来减少文件体积的能力',
'tinypng_developer_key_label' => '开发者 Key',
'tinypng_developer_key_comment' => '要了解如何生成此 Key请查看上面的提示',
'auto' => 'Auto',
'mode_exact' => 'Exact',
'mode_portrait' => 'Portrait',
'mode_landscape' => 'Landscape',
'mode_crop' => 'Crop',
'tinypng_invalid_key' => '输入的 tinypng 密钥无法验证,请检查密钥并重试',
'tinypng_compressed_images' => 'Compressed Images',
'tinypng_remaining_compressions' => 'Remaining Free Compressions',
'tinypng_days_until_reset' => 'Days until reset'
],
'permission' => [
'tab' => 'Image Resizer',
'label' => '管理设置'
]
];

View File

@ -0,0 +1,57 @@
<?php namespace ToughDeveloper\ImageResizer\Models;
use Model;
use Lang;
/**
* Settings Model
*/
class Settings extends Model
{
use \October\Rain\Database\Traits\Validation;
public $implement = ['System.Behaviors.SettingsModel'];
public $settingsCode = 'toughdeveloper_imageresizer_settings';
public $settingsFields = 'fields.yaml';
protected $casts = [
'default_offset_x' => 'integer',
'default_offset_y' => 'integer',
'default_quality' => 'integer',
'default_sharpen' => 'integer'
];
public $rules = [
'default_quality' => 'integer|between:0,100',
'default_sharpen' => 'integer|between:0,100',
'tinypng_developer_key' => 'required_if:enable_tinypng,1'
];
public $customMessages = [];
public function __construct(){
$this->customMessages['valid_tinypng_key'] = Lang::get('toughdeveloper.imageresizer::lang.settings.tinypng_invalid_key');
parent::__construct();
}
public function beforeValidate()
{
if ($this->enable_tinypng == 1) {
$this->rules['tinypng_developer_key'] .= '|valid_tinypng_key';
}
}
// Default setting data
public function initSettingsData()
{
$this->default_extension = 'auto';
$this->default_mode = 'auto';
$this->default_offset_x = 0;
$this->default_offset_y = 0;
$this->default_quality = 95;
$this->default_sharpen = 0;
}
}

View File

@ -0,0 +1 @@
<p><?= \Lang::get('toughdeveloper.imageresizer::lang.settings.tinypng_hint') ?></p>

View File

@ -0,0 +1,47 @@
<?php
$validKey = false;
$key = $this->formWidget->data->tinypng_developer_key;
if ($key) {
try {
\Tinify\setKey($key);
\Tinify\validate();
$validKey = true;
$compressionsThisMonth = (int) \Tinify\compressionCount();
$remainingFree = max(0, 500 - $compressionsThisMonth);
} catch(\Tinify\Exception $e) {
}
}
$currentDate = new DateTime(date('Y-m-d'));
$currentDate->add(new DateInterval('P1M'));
$firstDayOfNextMonth = $currentDate->format('Y-m-1');
$firstDayOfNextMonth = new DateTime($firstDayOfNextMonth);
$now = new DateTime();
$interval = $now->diff($firstDayOfNextMonth);
$daysUntilRenew = $interval->format('%a');
if ($validKey)
{
?>
<div class="scoreboard">
<div data-control="toolbar">
<div class="scoreboard-item control-chart" data-control="chart-pie">
<ul>
<li data-color="#95b753"><?= \Lang::get('toughdeveloper.imageresizer::lang.settings.tinypng_compressed_images') ?> <span><?=$compressionsThisMonth?></span></li>
<li data-color="#e5a91a"><?= \Lang::get('toughdeveloper.imageresizer::lang.settings.tinypng_remaining_compressions') ?> <span><?=$remainingFree?></span></li>
</ul>
</div>
<div class="scoreboard-item title-value">
<h4><?= \Lang::get('toughdeveloper.imageresizer::lang.settings.tinypng_days_until_reset') ?></h4>
<p><?=$daysUntilRenew?></p>
</div>
</div>
</div>
<?php
}

View File

@ -0,0 +1,106 @@
# ===================================
# Form Field Definitions
# ===================================
tabs:
fields:
not_found_image:
label: toughdeveloper.imageresizer::lang.settings.not_found_image_label
comment: toughdeveloper.imageresizer::lang.settings.not_found_image_comment
tab: toughdeveloper.imageresizer::lang.settings.tab_default
type: mediafinder
span: auto
default_mode:
label: toughdeveloper.imageresizer::lang.settings.default_mode_label
comment: toughdeveloper.imageresizer::lang.settings.default_mode_comment
tab: toughdeveloper.imageresizer::lang.settings.tab_default
type: dropdown
options:
'auto': toughdeveloper.imageresizer::lang.settings.auto
'exact': toughdeveloper.imageresizer::lang.settings.mode_exact
'portrait': toughdeveloper.imageresizer::lang.settings.mode_portrait
'landscape': toughdeveloper.imageresizer::lang.settings.mode_landscape
'crop': toughdeveloper.imageresizer::lang.settings.mode_crop
span: auto
default_offset_x:
label: toughdeveloper.imageresizer::lang.settings.default_offset_x_label
comment: toughdeveloper.imageresizer::lang.settings.default_offset_x_comment
tab: toughdeveloper.imageresizer::lang.settings.tab_default
default: 0
type: number
span: auto
default_offset_y:
label: toughdeveloper.imageresizer::lang.settings.default_offset_y_label
comment: toughdeveloper.imageresizer::lang.settings.default_offset_y_comment
tab: toughdeveloper.imageresizer::lang.settings.tab_default
default: 0
type: number
span: auto
default_extension:
label: toughdeveloper.imageresizer::lang.settings.default_extension_label
comment: toughdeveloper.imageresizer::lang.settings.default_extension_comment
tab: toughdeveloper.imageresizer::lang.settings.tab_default
type: dropdown
options:
'auto': toughdeveloper.imageresizer::lang.settings.auto
'jpg': 'jpg'
'jpeg': 'jpeg'
'gif': 'gif'
'png': 'png'
default: 'auto'
span: auto
default_quality:
label: toughdeveloper.imageresizer::lang.settings.default_quality_label
comment: toughdeveloper.imageresizer::lang.settings.default_quality_comment
tab: toughdeveloper.imageresizer::lang.settings.tab_default
type: number
default: 95
span: auto
default_sharpen:
label: toughdeveloper.imageresizer::lang.settings.default_sharpen_label
comment: toughdeveloper.imageresizer::lang.settings.default_sharpen_comment
tab: toughdeveloper.imageresizer::lang.settings.tab_default
type: number
default: 0
span: auto
tinypng_hint:
type: hint
path: $/toughdeveloper/imageresizer/models/settings/_tinypng_hint.htm
tab: toughdeveloper.imageresizer::lang.settings.tab_advanced
trigger:
action: show
field: enable_tinypng
condition: checked
tinypng_stats:
type: partial
path: $/toughdeveloper/imageresizer/models/settings/_tinypng_stats.htm
tab: toughdeveloper.imageresizer::lang.settings.tab_advanced
trigger:
action: show
field: enable_tinypng
condition: checked
enable_tinypng:
label: toughdeveloper.imageresizer::lang.settings.enable_tinypng_label
comment: toughdeveloper.imageresizer::lang.settings.enable_tinypng_comment
tab: toughdeveloper.imageresizer::lang.settings.tab_advanced
type: switch
span: auto
tinypng_developer_key:
label: toughdeveloper.imageresizer::lang.settings.tinypng_developer_key_label
comment: toughdeveloper.imageresizer::lang.settings.tinypng_developer_key_comment
tab: toughdeveloper.imageresizer::lang.settings.tab_advanced
span: auto
trigger:
action: show
field: enable_tinypng
condition: checked

View File

@ -0,0 +1,23 @@
1.0.1: First version of ImageResizer
1.0.2: Fixes bug where url set in config/app.php affecting rendering of image.
1.0.3: Adds Hungarian translation - thanks to Szabó Gergő
1.1.0: Adds default settings to admin - thanks to Szabó Gergő
1.2.0: Adds optional PNG compression support via Tiny PNG
1.2.1: Updates translations and allows jpg files to be compressed with Tiny PNG
1.2.2: Ensures false can be passed to auto width/height. Also improves URL parsing so different formats of app.url work as expected. Thanks to Emerge.
1.3.0: Adds TinyPNG API key validation, TinyPNG usage statistics and provides thumb backend list column type
1.3.1: Ensures plugin works as expected when October is installed to a sub-directory.
1.3.2: Adds option to skip compression of certain images, helpful to save credits.
1.3.3: Updates Hungarian translations - thanks to Szabó Gergő
1.3.4: Adds German translation - thanks to Christoph (emptynick)
1.3.5: !!! Changes path to cached image for builds of October 420+. Thanks to that0n3guy
1.3.6: Prevent infinite loop when custom not found image does not exist. Thanks to yapsr
1.4.0:
- Add imageWidth() and imageHeight() filters - @matteotrubini
- Adds fr translations - @FelixINX
- composer.json fixes - @DieterHolvoet and @LukeTowers
- Regenerate cached image if original has a different mtime - @kevinkoenen
- Delete temporary image copy - @multiwebinc
- Adds zh-cn translations - @everyx
- Spaces in filename are now handled properly - @mauserrifle
1.4.1: Only attempt to delete temp files if they still exist - @LukeTowers

View File

@ -0,0 +1,7 @@
<?php
// autoload.php @generated by Composer
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInit202259e63fe9c568e57706edaeec8df1::getLoader();

View File

@ -0,0 +1,445 @@
<?php
/*
* This file is part of Composer.
*
* (c) Nils Adermann <naderman@naderman.de>
* Jordi Boggiano <j.boggiano@seld.be>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Composer\Autoload;
/**
* ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
*
* $loader = new \Composer\Autoload\ClassLoader();
*
* // register classes with namespaces
* $loader->add('Symfony\Component', __DIR__.'/component');
* $loader->add('Symfony', __DIR__.'/framework');
*
* // activate the autoloader
* $loader->register();
*
* // to enable searching the include path (eg. for PEAR packages)
* $loader->setUseIncludePath(true);
*
* In this example, if you try to use a class in the Symfony\Component
* namespace or one of its children (Symfony\Component\Console for instance),
* the autoloader will first look for the class under the component/
* directory, and it will then fallback to the framework/ directory if not
* found before giving up.
*
* This class is loosely based on the Symfony UniversalClassLoader.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Jordi Boggiano <j.boggiano@seld.be>
* @see http://www.php-fig.org/psr/psr-0/
* @see http://www.php-fig.org/psr/psr-4/
*/
class ClassLoader
{
// PSR-4
private $prefixLengthsPsr4 = array();
private $prefixDirsPsr4 = array();
private $fallbackDirsPsr4 = array();
// PSR-0
private $prefixesPsr0 = array();
private $fallbackDirsPsr0 = array();
private $useIncludePath = false;
private $classMap = array();
private $classMapAuthoritative = false;
private $missingClasses = array();
private $apcuPrefix;
public function getPrefixes()
{
if (!empty($this->prefixesPsr0)) {
return call_user_func_array('array_merge', $this->prefixesPsr0);
}
return array();
}
public function getPrefixesPsr4()
{
return $this->prefixDirsPsr4;
}
public function getFallbackDirs()
{
return $this->fallbackDirsPsr0;
}
public function getFallbackDirsPsr4()
{
return $this->fallbackDirsPsr4;
}
public function getClassMap()
{
return $this->classMap;
}
/**
* @param array $classMap Class to filename map
*/
public function addClassMap(array $classMap)
{
if ($this->classMap) {
$this->classMap = array_merge($this->classMap, $classMap);
} else {
$this->classMap = $classMap;
}
}
/**
* Registers a set of PSR-0 directories for a given prefix, either
* appending or prepending to the ones previously set for this prefix.
*
* @param string $prefix The prefix
* @param array|string $paths The PSR-0 root directories
* @param bool $prepend Whether to prepend the directories
*/
public function add($prefix, $paths, $prepend = false)
{
if (!$prefix) {
if ($prepend) {
$this->fallbackDirsPsr0 = array_merge(
(array) $paths,
$this->fallbackDirsPsr0
);
} else {
$this->fallbackDirsPsr0 = array_merge(
$this->fallbackDirsPsr0,
(array) $paths
);
}
return;
}
$first = $prefix[0];
if (!isset($this->prefixesPsr0[$first][$prefix])) {
$this->prefixesPsr0[$first][$prefix] = (array) $paths;
return;
}
if ($prepend) {
$this->prefixesPsr0[$first][$prefix] = array_merge(
(array) $paths,
$this->prefixesPsr0[$first][$prefix]
);
} else {
$this->prefixesPsr0[$first][$prefix] = array_merge(
$this->prefixesPsr0[$first][$prefix],
(array) $paths
);
}
}
/**
* Registers a set of PSR-4 directories for a given namespace, either
* appending or prepending to the ones previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param array|string $paths The PSR-4 base directories
* @param bool $prepend Whether to prepend the directories
*
* @throws \InvalidArgumentException
*/
public function addPsr4($prefix, $paths, $prepend = false)
{
if (!$prefix) {
// Register directories for the root namespace.
if ($prepend) {
$this->fallbackDirsPsr4 = array_merge(
(array) $paths,
$this->fallbackDirsPsr4
);
} else {
$this->fallbackDirsPsr4 = array_merge(
$this->fallbackDirsPsr4,
(array) $paths
);
}
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
// Register directories for a new namespace.
$length = strlen($prefix);
if ('\\' !== $prefix[$length - 1]) {
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = (array) $paths;
} elseif ($prepend) {
// Prepend directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
(array) $paths,
$this->prefixDirsPsr4[$prefix]
);
} else {
// Append directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
$this->prefixDirsPsr4[$prefix],
(array) $paths
);
}
}
/**
* Registers a set of PSR-0 directories for a given prefix,
* replacing any others previously set for this prefix.
*
* @param string $prefix The prefix
* @param array|string $paths The PSR-0 base directories
*/
public function set($prefix, $paths)
{
if (!$prefix) {
$this->fallbackDirsPsr0 = (array) $paths;
} else {
$this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
}
}
/**
* Registers a set of PSR-4 directories for a given namespace,
* replacing any others previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param array|string $paths The PSR-4 base directories
*
* @throws \InvalidArgumentException
*/
public function setPsr4($prefix, $paths)
{
if (!$prefix) {
$this->fallbackDirsPsr4 = (array) $paths;
} else {
$length = strlen($prefix);
if ('\\' !== $prefix[$length - 1]) {
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = (array) $paths;
}
}
/**
* Turns on searching the include path for class files.
*
* @param bool $useIncludePath
*/
public function setUseIncludePath($useIncludePath)
{
$this->useIncludePath = $useIncludePath;
}
/**
* Can be used to check if the autoloader uses the include path to check
* for classes.
*
* @return bool
*/
public function getUseIncludePath()
{
return $this->useIncludePath;
}
/**
* Turns off searching the prefix and fallback directories for classes
* that have not been registered with the class map.
*
* @param bool $classMapAuthoritative
*/
public function setClassMapAuthoritative($classMapAuthoritative)
{
$this->classMapAuthoritative = $classMapAuthoritative;
}
/**
* Should class lookup fail if not found in the current class map?
*
* @return bool
*/
public function isClassMapAuthoritative()
{
return $this->classMapAuthoritative;
}
/**
* APCu prefix to use to cache found/not-found classes, if the extension is enabled.
*
* @param string|null $apcuPrefix
*/
public function setApcuPrefix($apcuPrefix)
{
$this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
}
/**
* The APCu prefix in use, or null if APCu caching is not enabled.
*
* @return string|null
*/
public function getApcuPrefix()
{
return $this->apcuPrefix;
}
/**
* Registers this instance as an autoloader.
*
* @param bool $prepend Whether to prepend the autoloader or not
*/
public function register($prepend = false)
{
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
}
/**
* Unregisters this instance as an autoloader.
*/
public function unregister()
{
spl_autoload_unregister(array($this, 'loadClass'));
}
/**
* Loads the given class or interface.
*
* @param string $class The name of the class
* @return bool|null True if loaded, null otherwise
*/
public function loadClass($class)
{
if ($file = $this->findFile($class)) {
includeFile($file);
return true;
}
}
/**
* Finds the path to the file where the class is defined.
*
* @param string $class The name of the class
*
* @return string|false The path if found, false otherwise
*/
public function findFile($class)
{
// class map lookup
if (isset($this->classMap[$class])) {
return $this->classMap[$class];
}
if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
return false;
}
if (null !== $this->apcuPrefix) {
$file = apcu_fetch($this->apcuPrefix.$class, $hit);
if ($hit) {
return $file;
}
}
$file = $this->findFileWithExtension($class, '.php');
// Search for Hack files if we are running on HHVM
if (false === $file && defined('HHVM_VERSION')) {
$file = $this->findFileWithExtension($class, '.hh');
}
if (null !== $this->apcuPrefix) {
apcu_add($this->apcuPrefix.$class, $file);
}
if (false === $file) {
// Remember that this class does not exist.
$this->missingClasses[$class] = true;
}
return $file;
}
private function findFileWithExtension($class, $ext)
{
// PSR-4 lookup
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
$first = $class[0];
if (isset($this->prefixLengthsPsr4[$first])) {
$subPath = $class;
while (false !== $lastPos = strrpos($subPath, '\\')) {
$subPath = substr($subPath, 0, $lastPos);
$search = $subPath . '\\';
if (isset($this->prefixDirsPsr4[$search])) {
$pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
foreach ($this->prefixDirsPsr4[$search] as $dir) {
if (file_exists($file = $dir . $pathEnd)) {
return $file;
}
}
}
}
}
// PSR-4 fallback dirs
foreach ($this->fallbackDirsPsr4 as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
return $file;
}
}
// PSR-0 lookup
if (false !== $pos = strrpos($class, '\\')) {
// namespaced class name
$logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
} else {
// PEAR-like class name
$logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
}
if (isset($this->prefixesPsr0[$first])) {
foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
if (0 === strpos($class, $prefix)) {
foreach ($dirs as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
return $file;
}
}
}
}
}
// PSR-0 fallback dirs
foreach ($this->fallbackDirsPsr0 as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
return $file;
}
}
// PSR-0 include paths.
if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
return $file;
}
return false;
}
}
/**
* Scope isolated include.
*
* Prevents access to $this/self from included files.
*/
function includeFile($file)
{
include $file;
}

View File

@ -0,0 +1,21 @@
Copyright (c) Nils Adermann, Jordi Boggiano
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@ -0,0 +1,9 @@
<?php
// autoload_classmap.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
);

View File

@ -0,0 +1,11 @@
<?php
// autoload_files.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
'74ed299072414d276bb7568fe71d5b0c' => $vendorDir . '/tinify/tinify/lib/Tinify.php',
'9635627915aaea7a98d6d14d04ca5b56' => $vendorDir . '/tinify/tinify/lib/Tinify/Exception.php',
);

View File

@ -0,0 +1,9 @@
<?php
// autoload_namespaces.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
);

View File

@ -0,0 +1,11 @@
<?php
// autoload_psr4.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
'Tinify\\' => array($vendorDir . '/tinify/tinify/lib/Tinify'),
'Composer\\Installers\\' => array($vendorDir . '/composer/installers/src/Composer/Installers'),
);

View File

@ -0,0 +1,70 @@
<?php
// autoload_real.php @generated by Composer
class ComposerAutoloaderInit202259e63fe9c568e57706edaeec8df1
{
private static $loader;
public static function loadClassLoader($class)
{
if ('Composer\Autoload\ClassLoader' === $class) {
require __DIR__ . '/ClassLoader.php';
}
}
public static function getLoader()
{
if (null !== self::$loader) {
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInit202259e63fe9c568e57706edaeec8df1', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
spl_autoload_unregister(array('ComposerAutoloaderInit202259e63fe9c568e57706edaeec8df1', 'loadClassLoader'));
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
if ($useStaticLoader) {
require_once __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInit202259e63fe9c568e57706edaeec8df1::getInitializer($loader));
} else {
$map = require __DIR__ . '/autoload_namespaces.php';
foreach ($map as $namespace => $path) {
$loader->set($namespace, $path);
}
$map = require __DIR__ . '/autoload_psr4.php';
foreach ($map as $namespace => $path) {
$loader->setPsr4($namespace, $path);
}
$classMap = require __DIR__ . '/autoload_classmap.php';
if ($classMap) {
$loader->addClassMap($classMap);
}
}
$loader->register(true);
if ($useStaticLoader) {
$includeFiles = Composer\Autoload\ComposerStaticInit202259e63fe9c568e57706edaeec8df1::$files;
} else {
$includeFiles = require __DIR__ . '/autoload_files.php';
}
foreach ($includeFiles as $fileIdentifier => $file) {
composerRequire202259e63fe9c568e57706edaeec8df1($fileIdentifier, $file);
}
return $loader;
}
}
function composerRequire202259e63fe9c568e57706edaeec8df1($fileIdentifier, $file)
{
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
require $file;
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
}
}

View File

@ -0,0 +1,44 @@
<?php
// autoload_static.php @generated by Composer
namespace Composer\Autoload;
class ComposerStaticInit202259e63fe9c568e57706edaeec8df1
{
public static $files = array (
'74ed299072414d276bb7568fe71d5b0c' => __DIR__ . '/..' . '/tinify/tinify/lib/Tinify.php',
'9635627915aaea7a98d6d14d04ca5b56' => __DIR__ . '/..' . '/tinify/tinify/lib/Tinify/Exception.php',
);
public static $prefixLengthsPsr4 = array (
'T' =>
array (
'Tinify\\' => 7,
),
'C' =>
array (
'Composer\\Installers\\' => 20,
),
);
public static $prefixDirsPsr4 = array (
'Tinify\\' =>
array (
0 => __DIR__ . '/..' . '/tinify/tinify/lib/Tinify',
),
'Composer\\Installers\\' =>
array (
0 => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers',
),
);
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInit202259e63fe9c568e57706edaeec8df1::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInit202259e63fe9c568e57706edaeec8df1::$prefixDirsPsr4;
}, null, ClassLoader::class);
}
}

View File

@ -0,0 +1,189 @@
[
{
"name": "composer/installers",
"version": "v1.9.0",
"version_normalized": "1.9.0.0",
"source": {
"type": "git",
"url": "https://github.com/composer/installers.git",
"reference": "b93bcf0fa1fccb0b7d176b0967d969691cd74cca"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/composer/installers/zipball/b93bcf0fa1fccb0b7d176b0967d969691cd74cca",
"reference": "b93bcf0fa1fccb0b7d176b0967d969691cd74cca",
"shasum": ""
},
"require": {
"composer-plugin-api": "^1.0 || ^2.0"
},
"replace": {
"roundcube/plugin-installer": "*",
"shama/baton": "*"
},
"require-dev": {
"composer/composer": "1.6.* || 2.0.*@dev",
"composer/semver": "1.0.* || 2.0.*@dev",
"phpunit/phpunit": "^4.8.36",
"sebastian/comparator": "^1.2.4",
"symfony/process": "^2.3"
},
"time": "2020-04-07T06:57:05+00:00",
"type": "composer-plugin",
"extra": {
"class": "Composer\\Installers\\Plugin",
"branch-alias": {
"dev-master": "1.0-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-4": {
"Composer\\Installers\\": "src/Composer/Installers"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Kyle Robinson Young",
"email": "kyle@dontkry.com",
"homepage": "https://github.com/shama"
}
],
"description": "A multi-framework Composer library installer",
"homepage": "https://composer.github.io/installers/",
"keywords": [
"Craft",
"Dolibarr",
"Eliasis",
"Hurad",
"ImageCMS",
"Kanboard",
"Lan Management System",
"MODX Evo",
"MantisBT",
"Mautic",
"Maya",
"OXID",
"Plentymarkets",
"Porto",
"RadPHP",
"SMF",
"Thelia",
"Whmcs",
"WolfCMS",
"agl",
"aimeos",
"annotatecms",
"attogram",
"bitrix",
"cakephp",
"chef",
"cockpit",
"codeigniter",
"concrete5",
"croogo",
"dokuwiki",
"drupal",
"eZ Platform",
"elgg",
"expressionengine",
"fuelphp",
"grav",
"installer",
"itop",
"joomla",
"known",
"kohana",
"laravel",
"lavalite",
"lithium",
"magento",
"majima",
"mako",
"mediawiki",
"modulework",
"modx",
"moodle",
"osclass",
"phpbb",
"piwik",
"ppi",
"puppet",
"pxcms",
"reindex",
"roundcube",
"shopware",
"silverstripe",
"sydes",
"sylius",
"symfony",
"typo3",
"wordpress",
"yawik",
"zend",
"zikula"
]
},
{
"name": "tinify/tinify",
"version": "1.5.2",
"version_normalized": "1.5.2.0",
"source": {
"type": "git",
"url": "https://github.com/tinify/tinify-php.git",
"reference": "b15d1f31d94d9b06e60251543cc918f426f0d55b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/tinify/tinify-php/zipball/b15d1f31d94d9b06e60251543cc918f426f0d55b",
"reference": "b15d1f31d94d9b06e60251543cc918f426f0d55b",
"shasum": ""
},
"require": {
"ext-curl": "*",
"ext-json": "*",
"lib-curl": ">=7.20.0",
"php": ">=5.3.0"
},
"require-dev": {
"phpunit/phpunit": "~4.0",
"symfony/yaml": "~2.0"
},
"time": "2017-07-19T12:26:04+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"files": [
"lib/Tinify.php",
"lib/Tinify/Exception.php"
],
"psr-4": {
"Tinify\\": "lib/Tinify/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Rolf Timmermans",
"email": "rolftimmermans@voormedia.com"
}
],
"description": "PHP client for the Tinify API. Tinify compresses your images intelligently. Read more at https://tinify.com.",
"homepage": "https://tinify.com/developers",
"keywords": [
"api",
"compress",
"images",
"tinify",
"tinyjpg",
"tinypng"
]
}
]

View File

@ -0,0 +1,19 @@
Copyright (c) 2012 Kyle Robinson Young
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@ -0,0 +1,112 @@
{
"name": "composer/installers",
"type": "composer-plugin",
"license": "MIT",
"description": "A multi-framework Composer library installer",
"keywords": [
"installer",
"Aimeos",
"AGL",
"AnnotateCms",
"Attogram",
"Bitrix",
"CakePHP",
"Chef",
"Cockpit",
"CodeIgniter",
"concrete5",
"Craft",
"Croogo",
"DokuWiki",
"Dolibarr",
"Drupal",
"Elgg",
"Eliasis",
"ExpressionEngine",
"eZ Platform",
"FuelPHP",
"Grav",
"Hurad",
"ImageCMS",
"iTop",
"Joomla",
"Kanboard",
"Known",
"Kohana",
"Lan Management System",
"Laravel",
"Lavalite",
"Lithium",
"Magento",
"majima",
"Mako",
"MantisBT",
"Mautic",
"Maya",
"MODX",
"MODX Evo",
"MediaWiki",
"OXID",
"osclass",
"MODULEWork",
"Moodle",
"Piwik",
"pxcms",
"phpBB",
"Plentymarkets",
"PPI",
"Puppet",
"Porto",
"RadPHP",
"ReIndex",
"Roundcube",
"shopware",
"SilverStripe",
"SMF",
"SyDES",
"Sylius",
"symfony",
"Thelia",
"TYPO3",
"WHMCS",
"WolfCMS",
"WordPress",
"YAWIK",
"Zend",
"Zikula"
],
"homepage": "https://composer.github.io/installers/",
"authors": [
{
"name": "Kyle Robinson Young",
"email": "kyle@dontkry.com",
"homepage": "https://github.com/shama"
}
],
"autoload": {
"psr-4": { "Composer\\Installers\\": "src/Composer/Installers" }
},
"extra": {
"class": "Composer\\Installers\\Plugin",
"branch-alias": {
"dev-master": "1.0-dev"
}
},
"replace": {
"shama/baton": "*",
"roundcube/plugin-installer": "*"
},
"require": {
"composer-plugin-api": "^1.0 || ^2.0"
},
"require-dev": {
"composer/composer": "1.6.* || 2.0.*@dev",
"composer/semver": "1.0.* || 2.0.*@dev",
"phpunit/phpunit": "^4.8.36",
"sebastian/comparator": "^1.2.4",
"symfony/process": "^2.3"
},
"scripts": {
"test": "phpunit"
}
}

View File

@ -0,0 +1,21 @@
<?php
namespace Composer\Installers;
class AglInstaller extends BaseInstaller
{
protected $locations = array(
'module' => 'More/{$name}/',
);
/**
* Format package name to CamelCase
*/
public function inflectPackageVars($vars)
{
$vars['name'] = preg_replace_callback('/(?:^|_|-)(.?)/', function ($matches) {
return strtoupper($matches[1]);
}, $vars['name']);
return $vars;
}
}

View File

@ -0,0 +1,9 @@
<?php
namespace Composer\Installers;
class AimeosInstaller extends BaseInstaller
{
protected $locations = array(
'extension' => 'ext/{$name}/',
);
}

View File

@ -0,0 +1,11 @@
<?php
namespace Composer\Installers;
class AnnotateCmsInstaller extends BaseInstaller
{
protected $locations = array(
'module' => 'addons/modules/{$name}/',
'component' => 'addons/components/{$name}/',
'service' => 'addons/services/{$name}/',
);
}

View File

@ -0,0 +1,49 @@
<?php
namespace Composer\Installers;
class AsgardInstaller extends BaseInstaller
{
protected $locations = array(
'module' => 'Modules/{$name}/',
'theme' => 'Themes/{$name}/'
);
/**
* Format package name.
*
* For package type asgard-module, cut off a trailing '-plugin' if present.
*
* For package type asgard-theme, cut off a trailing '-theme' if present.
*
*/
public function inflectPackageVars($vars)
{
if ($vars['type'] === 'asgard-module') {
return $this->inflectPluginVars($vars);
}
if ($vars['type'] === 'asgard-theme') {
return $this->inflectThemeVars($vars);
}
return $vars;
}
protected function inflectPluginVars($vars)
{
$vars['name'] = preg_replace('/-module$/', '', $vars['name']);
$vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
$vars['name'] = str_replace(' ', '', ucwords($vars['name']));
return $vars;
}
protected function inflectThemeVars($vars)
{
$vars['name'] = preg_replace('/-theme$/', '', $vars['name']);
$vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
$vars['name'] = str_replace(' ', '', ucwords($vars['name']));
return $vars;
}
}

View File

@ -0,0 +1,9 @@
<?php
namespace Composer\Installers;
class AttogramInstaller extends BaseInstaller
{
protected $locations = array(
'module' => 'modules/{$name}/',
);
}

View File

@ -0,0 +1,137 @@
<?php
namespace Composer\Installers;
use Composer\IO\IOInterface;
use Composer\Composer;
use Composer\Package\PackageInterface;
abstract class BaseInstaller
{
protected $locations = array();
protected $composer;
protected $package;
protected $io;
/**
* Initializes base installer.
*
* @param PackageInterface $package
* @param Composer $composer
* @param IOInterface $io
*/
public function __construct(PackageInterface $package = null, Composer $composer = null, IOInterface $io = null)
{
$this->composer = $composer;
$this->package = $package;
$this->io = $io;
}
/**
* Return the install path based on package type.
*
* @param PackageInterface $package
* @param string $frameworkType
* @return string
*/
public function getInstallPath(PackageInterface $package, $frameworkType = '')
{
$type = $this->package->getType();
$prettyName = $this->package->getPrettyName();
if (strpos($prettyName, '/') !== false) {
list($vendor, $name) = explode('/', $prettyName);
} else {
$vendor = '';
$name = $prettyName;
}
$availableVars = $this->inflectPackageVars(compact('name', 'vendor', 'type'));
$extra = $package->getExtra();
if (!empty($extra['installer-name'])) {
$availableVars['name'] = $extra['installer-name'];
}
if ($this->composer->getPackage()) {
$extra = $this->composer->getPackage()->getExtra();
if (!empty($extra['installer-paths'])) {
$customPath = $this->mapCustomInstallPaths($extra['installer-paths'], $prettyName, $type, $vendor);
if ($customPath !== false) {
return $this->templatePath($customPath, $availableVars);
}
}
}
$packageType = substr($type, strlen($frameworkType) + 1);
$locations = $this->getLocations();
if (!isset($locations[$packageType])) {
throw new \InvalidArgumentException(sprintf('Package type "%s" is not supported', $type));
}
return $this->templatePath($locations[$packageType], $availableVars);
}
/**
* For an installer to override to modify the vars per installer.
*
* @param array $vars
* @return array
*/
public function inflectPackageVars($vars)
{
return $vars;
}
/**
* Gets the installer's locations
*
* @return array
*/
public function getLocations()
{
return $this->locations;
}
/**
* Replace vars in a path
*
* @param string $path
* @param array $vars
* @return string
*/
protected function templatePath($path, array $vars = array())
{
if (strpos($path, '{') !== false) {
extract($vars);
preg_match_all('@\{\$([A-Za-z0-9_]*)\}@i', $path, $matches);
if (!empty($matches[1])) {
foreach ($matches[1] as $var) {
$path = str_replace('{$' . $var . '}', $$var, $path);
}
}
}
return $path;
}
/**
* Search through a passed paths array for a custom install path.
*
* @param array $paths
* @param string $name
* @param string $type
* @param string $vendor = NULL
* @return string
*/
protected function mapCustomInstallPaths(array $paths, $name, $type, $vendor = NULL)
{
foreach ($paths as $path => $names) {
$names = (array) $names;
if (in_array($name, $names) || in_array('type:' . $type, $names) || in_array('vendor:' . $vendor, $names)) {
return $path;
}
}
return false;
}
}

View File

@ -0,0 +1,126 @@
<?php
namespace Composer\Installers;
use Composer\Util\Filesystem;
/**
* Installer for Bitrix Framework. Supported types of extensions:
* - `bitrix-d7-module` copy the module to directory `bitrix/modules/<vendor>.<name>`.
* - `bitrix-d7-component` copy the component to directory `bitrix/components/<vendor>/<name>`.
* - `bitrix-d7-template` copy the template to directory `bitrix/templates/<vendor>_<name>`.
*
* You can set custom path to directory with Bitrix kernel in `composer.json`:
*
* ```json
* {
* "extra": {
* "bitrix-dir": "s1/bitrix"
* }
* }
* ```
*
* @author Nik Samokhvalov <nik@samokhvalov.info>
* @author Denis Kulichkin <onexhovia@gmail.com>
*/
class BitrixInstaller extends BaseInstaller
{
protected $locations = array(
'module' => '{$bitrix_dir}/modules/{$name}/', // deprecated, remove on the major release (Backward compatibility will be broken)
'component' => '{$bitrix_dir}/components/{$name}/', // deprecated, remove on the major release (Backward compatibility will be broken)
'theme' => '{$bitrix_dir}/templates/{$name}/', // deprecated, remove on the major release (Backward compatibility will be broken)
'd7-module' => '{$bitrix_dir}/modules/{$vendor}.{$name}/',
'd7-component' => '{$bitrix_dir}/components/{$vendor}/{$name}/',
'd7-template' => '{$bitrix_dir}/templates/{$vendor}_{$name}/',
);
/**
* @var array Storage for informations about duplicates at all the time of installation packages.
*/
private static $checkedDuplicates = array();
/**
* {@inheritdoc}
*/
public function inflectPackageVars($vars)
{
if ($this->composer->getPackage()) {
$extra = $this->composer->getPackage()->getExtra();
if (isset($extra['bitrix-dir'])) {
$vars['bitrix_dir'] = $extra['bitrix-dir'];
}
}
if (!isset($vars['bitrix_dir'])) {
$vars['bitrix_dir'] = 'bitrix';
}
return parent::inflectPackageVars($vars);
}
/**
* {@inheritdoc}
*/
protected function templatePath($path, array $vars = array())
{
$templatePath = parent::templatePath($path, $vars);
$this->checkDuplicates($templatePath, $vars);
return $templatePath;
}
/**
* Duplicates search packages.
*
* @param string $path
* @param array $vars
*/
protected function checkDuplicates($path, array $vars = array())
{
$packageType = substr($vars['type'], strlen('bitrix') + 1);
$localDir = explode('/', $vars['bitrix_dir']);
array_pop($localDir);
$localDir[] = 'local';
$localDir = implode('/', $localDir);
$oldPath = str_replace(
array('{$bitrix_dir}', '{$name}'),
array($localDir, $vars['name']),
$this->locations[$packageType]
);
if (in_array($oldPath, static::$checkedDuplicates)) {
return;
}
if ($oldPath !== $path && file_exists($oldPath) && $this->io && $this->io->isInteractive()) {
$this->io->writeError(' <error>Duplication of packages:</error>');
$this->io->writeError(' <info>Package ' . $oldPath . ' will be called instead package ' . $path . '</info>');
while (true) {
switch ($this->io->ask(' <info>Delete ' . $oldPath . ' [y,n,?]?</info> ', '?')) {
case 'y':
$fs = new Filesystem();
$fs->removeDirectory($oldPath);
break 2;
case 'n':
break 2;
case '?':
default:
$this->io->writeError(array(
' y - delete package ' . $oldPath . ' and to continue with the installation',
' n - don\'t delete and to continue with the installation',
));
$this->io->writeError(' ? - print help');
break;
}
}
}
static::$checkedDuplicates[] = $oldPath;
}
}

View File

@ -0,0 +1,9 @@
<?php
namespace Composer\Installers;
class BonefishInstaller extends BaseInstaller
{
protected $locations = array(
'package' => 'Packages/{$vendor}/{$name}/'
);
}

View File

@ -0,0 +1,72 @@
<?php
namespace Composer\Installers;
use Composer\DependencyResolver\Pool;
class CakePHPInstaller extends BaseInstaller
{
protected $locations = array(
'plugin' => 'Plugin/{$name}/',
);
/**
* Format package name to CamelCase
*/
public function inflectPackageVars($vars)
{
if ($this->matchesCakeVersion('>=', '3.0.0')) {
return $vars;
}
$nameParts = explode('/', $vars['name']);
foreach ($nameParts as &$value) {
$value = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $value));
$value = str_replace(array('-', '_'), ' ', $value);
$value = str_replace(' ', '', ucwords($value));
}
$vars['name'] = implode('/', $nameParts);
return $vars;
}
/**
* Change the default plugin location when cakephp >= 3.0
*/
public function getLocations()
{
if ($this->matchesCakeVersion('>=', '3.0.0')) {
$this->locations['plugin'] = $this->composer->getConfig()->get('vendor-dir') . '/{$vendor}/{$name}/';
}
return $this->locations;
}
/**
* Check if CakePHP version matches against a version
*
* @param string $matcher
* @param string $version
* @return bool
*/
protected function matchesCakeVersion($matcher, $version)
{
if (class_exists('Composer\Semver\Constraint\MultiConstraint')) {
$multiClass = 'Composer\Semver\Constraint\MultiConstraint';
$constraintClass = 'Composer\Semver\Constraint\Constraint';
} else {
$multiClass = 'Composer\Package\LinkConstraint\MultiConstraint';
$constraintClass = 'Composer\Package\LinkConstraint\VersionConstraint';
}
$repositoryManager = $this->composer->getRepositoryManager();
if (! $repositoryManager) {
return false;
}
$repos = $repositoryManager->getLocalRepository();
if (!$repos) {
return false;
}
return $repos->findPackage('cakephp/cakephp', new $constraintClass($matcher, $version)) !== null;
}
}

View File

@ -0,0 +1,11 @@
<?php
namespace Composer\Installers;
class ChefInstaller extends BaseInstaller
{
protected $locations = array(
'cookbook' => 'Chef/{$vendor}/{$name}/',
'role' => 'Chef/roles/{$name}/',
);
}

View File

@ -0,0 +1,9 @@
<?php
namespace Composer\Installers;
class CiviCrmInstaller extends BaseInstaller
{
protected $locations = array(
'ext' => 'ext/{$name}/'
);
}

View File

@ -0,0 +1,10 @@
<?php
namespace Composer\Installers;
class ClanCatsFrameworkInstaller extends BaseInstaller
{
protected $locations = array(
'ship' => 'CCF/orbit/{$name}/',
'theme' => 'CCF/app/themes/{$name}/',
);
}

View File

@ -0,0 +1,34 @@
<?php
namespace Composer\Installers;
class CockpitInstaller extends BaseInstaller
{
protected $locations = array(
'module' => 'cockpit/modules/addons/{$name}/',
);
/**
* Format module name.
*
* Strip `module-` prefix from package name.
*
* @param array @vars
*
* @return array
*/
public function inflectPackageVars($vars)
{
if ($vars['type'] == 'cockpit-module') {
return $this->inflectModuleVars($vars);
}
return $vars;
}
public function inflectModuleVars($vars)
{
$vars['name'] = ucfirst(preg_replace('/cockpit-/i', '', $vars['name']));
return $vars;
}
}

View File

@ -0,0 +1,11 @@
<?php
namespace Composer\Installers;
class CodeIgniterInstaller extends BaseInstaller
{
protected $locations = array(
'library' => 'application/libraries/{$name}/',
'third-party' => 'application/third_party/{$name}/',
'module' => 'application/modules/{$name}/',
);
}

View File

@ -0,0 +1,13 @@
<?php
namespace Composer\Installers;
class Concrete5Installer extends BaseInstaller
{
protected $locations = array(
'core' => 'concrete/',
'block' => 'application/blocks/{$name}/',
'package' => 'packages/{$name}/',
'theme' => 'application/themes/{$name}/',
'update' => 'updates/{$name}/',
);
}

View File

@ -0,0 +1,35 @@
<?php
namespace Composer\Installers;
/**
* Installer for Craft Plugins
*/
class CraftInstaller extends BaseInstaller
{
const NAME_PREFIX = 'craft';
const NAME_SUFFIX = 'plugin';
protected $locations = array(
'plugin' => 'craft/plugins/{$name}/',
);
/**
* Strip `craft-` prefix and/or `-plugin` suffix from package names
*
* @param array $vars
*
* @return array
*/
final public function inflectPackageVars($vars)
{
return $this->inflectPluginVars($vars);
}
private function inflectPluginVars($vars)
{
$vars['name'] = preg_replace('/-' . self::NAME_SUFFIX . '$/i', '', $vars['name']);
$vars['name'] = preg_replace('/^' . self::NAME_PREFIX . '-/i', '', $vars['name']);
return $vars;
}
}

View File

@ -0,0 +1,21 @@
<?php
namespace Composer\Installers;
class CroogoInstaller extends BaseInstaller
{
protected $locations = array(
'plugin' => 'Plugin/{$name}/',
'theme' => 'View/Themed/{$name}/',
);
/**
* Format package name to CamelCase
*/
public function inflectPackageVars($vars)
{
$vars['name'] = strtolower(str_replace(array('-', '_'), ' ', $vars['name']));
$vars['name'] = str_replace(' ', '', ucwords($vars['name']));
return $vars;
}
}

View File

@ -0,0 +1,10 @@
<?php
namespace Composer\Installers;
class DecibelInstaller extends BaseInstaller
{
/** @var array */
protected $locations = array(
'app' => 'app/{$name}/',
);
}

View File

@ -0,0 +1,10 @@
<?php
namespace Composer\Installers;
class DframeInstaller extends BaseInstaller
{
protected $locations = array(
'module' => 'modules/{$vendor}/{$name}/',
);
}

View File

@ -0,0 +1,50 @@
<?php
namespace Composer\Installers;
class DokuWikiInstaller extends BaseInstaller
{
protected $locations = array(
'plugin' => 'lib/plugins/{$name}/',
'template' => 'lib/tpl/{$name}/',
);
/**
* Format package name.
*
* For package type dokuwiki-plugin, cut off a trailing '-plugin',
* or leading dokuwiki_ if present.
*
* For package type dokuwiki-template, cut off a trailing '-template' if present.
*
*/
public function inflectPackageVars($vars)
{
if ($vars['type'] === 'dokuwiki-plugin') {
return $this->inflectPluginVars($vars);
}
if ($vars['type'] === 'dokuwiki-template') {
return $this->inflectTemplateVars($vars);
}
return $vars;
}
protected function inflectPluginVars($vars)
{
$vars['name'] = preg_replace('/-plugin$/', '', $vars['name']);
$vars['name'] = preg_replace('/^dokuwiki_?-?/', '', $vars['name']);
return $vars;
}
protected function inflectTemplateVars($vars)
{
$vars['name'] = preg_replace('/-template$/', '', $vars['name']);
$vars['name'] = preg_replace('/^dokuwiki_?-?/', '', $vars['name']);
return $vars;
}
}

View File

@ -0,0 +1,16 @@
<?php
namespace Composer\Installers;
/**
* Class DolibarrInstaller
*
* @package Composer\Installers
* @author Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
*/
class DolibarrInstaller extends BaseInstaller
{
//TODO: Add support for scripts and themes
protected $locations = array(
'module' => 'htdocs/custom/{$name}/',
);
}

View File

@ -0,0 +1,22 @@
<?php
namespace Composer\Installers;
class DrupalInstaller extends BaseInstaller
{
protected $locations = array(
'core' => 'core/',
'module' => 'modules/{$name}/',
'theme' => 'themes/{$name}/',
'library' => 'libraries/{$name}/',
'profile' => 'profiles/{$name}/',
'database-driver' => 'drivers/lib/Drupal/Driver/Database/{$name}/',
'drush' => 'drush/{$name}/',
'custom-theme' => 'themes/custom/{$name}/',
'custom-module' => 'modules/custom/{$name}/',
'custom-profile' => 'profiles/custom/{$name}/',
'drupal-multisite' => 'sites/{$name}/',
'console' => 'console/{$name}/',
'console-language' => 'console/language/{$name}/',
'config' => 'config/sync/',
);
}

View File

@ -0,0 +1,9 @@
<?php
namespace Composer\Installers;
class ElggInstaller extends BaseInstaller
{
protected $locations = array(
'plugin' => 'mod/{$name}/',
);
}

View File

@ -0,0 +1,12 @@
<?php
namespace Composer\Installers;
class EliasisInstaller extends BaseInstaller
{
protected $locations = array(
'component' => 'components/{$name}/',
'module' => 'modules/{$name}/',
'plugin' => 'plugins/{$name}/',
'template' => 'templates/{$name}/',
);
}

View File

@ -0,0 +1,29 @@
<?php
namespace Composer\Installers;
use Composer\Package\PackageInterface;
class ExpressionEngineInstaller extends BaseInstaller
{
protected $locations = array();
private $ee2Locations = array(
'addon' => 'system/expressionengine/third_party/{$name}/',
'theme' => 'themes/third_party/{$name}/',
);
private $ee3Locations = array(
'addon' => 'system/user/addons/{$name}/',
'theme' => 'themes/user/{$name}/',
);
public function getInstallPath(PackageInterface $package, $frameworkType = '')
{
$version = "{$frameworkType}Locations";
$this->locations = $this->$version;
return parent::getInstallPath($package, $frameworkType);
}
}

View File

@ -0,0 +1,10 @@
<?php
namespace Composer\Installers;
class EzPlatformInstaller extends BaseInstaller
{
protected $locations = array(
'meta-assets' => 'web/assets/ezplatform/',
'assets' => 'web/assets/ezplatform/{$name}/',
);
}

View File

@ -0,0 +1,11 @@
<?php
namespace Composer\Installers;
class FuelInstaller extends BaseInstaller
{
protected $locations = array(
'module' => 'fuel/app/modules/{$name}/',
'package' => 'fuel/packages/{$name}/',
'theme' => 'fuel/app/themes/{$name}/',
);
}

View File

@ -0,0 +1,9 @@
<?php
namespace Composer\Installers;
class FuelphpInstaller extends BaseInstaller
{
protected $locations = array(
'component' => 'components/{$name}/',
);
}

View File

@ -0,0 +1,30 @@
<?php
namespace Composer\Installers;
class GravInstaller extends BaseInstaller
{
protected $locations = array(
'plugin' => 'user/plugins/{$name}/',
'theme' => 'user/themes/{$name}/',
);
/**
* Format package name
*
* @param array $vars
*
* @return array
*/
public function inflectPackageVars($vars)
{
$restrictedWords = implode('|', array_keys($this->locations));
$vars['name'] = strtolower($vars['name']);
$vars['name'] = preg_replace('/^(?:grav-)?(?:(?:'.$restrictedWords.')-)?(.*?)(?:-(?:'.$restrictedWords.'))?$/ui',
'$1',
$vars['name']
);
return $vars;
}
}

View File

@ -0,0 +1,25 @@
<?php
namespace Composer\Installers;
class HuradInstaller extends BaseInstaller
{
protected $locations = array(
'plugin' => 'plugins/{$name}/',
'theme' => 'plugins/{$name}/',
);
/**
* Format package name to CamelCase
*/
public function inflectPackageVars($vars)
{
$nameParts = explode('/', $vars['name']);
foreach ($nameParts as &$value) {
$value = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $value));
$value = str_replace(array('-', '_'), ' ', $value);
$value = str_replace(' ', '', ucwords($value));
}
$vars['name'] = implode('/', $nameParts);
return $vars;
}
}

View File

@ -0,0 +1,11 @@
<?php
namespace Composer\Installers;
class ImageCMSInstaller extends BaseInstaller
{
protected $locations = array(
'template' => 'templates/{$name}/',
'module' => 'application/modules/{$name}/',
'library' => 'application/libraries/{$name}/',
);
}

View File

@ -0,0 +1,280 @@
<?php
namespace Composer\Installers;
use Composer\Composer;
use Composer\Installer\BinaryInstaller;
use Composer\Installer\LibraryInstaller;
use Composer\IO\IOInterface;
use Composer\Package\PackageInterface;
use Composer\Repository\InstalledRepositoryInterface;
use Composer\Util\Filesystem;
class Installer extends LibraryInstaller
{
/**
* Package types to installer class map
*
* @var array
*/
private $supportedTypes = array(
'aimeos' => 'AimeosInstaller',
'asgard' => 'AsgardInstaller',
'attogram' => 'AttogramInstaller',
'agl' => 'AglInstaller',
'annotatecms' => 'AnnotateCmsInstaller',
'bitrix' => 'BitrixInstaller',
'bonefish' => 'BonefishInstaller',
'cakephp' => 'CakePHPInstaller',
'chef' => 'ChefInstaller',
'civicrm' => 'CiviCrmInstaller',
'ccframework' => 'ClanCatsFrameworkInstaller',
'cockpit' => 'CockpitInstaller',
'codeigniter' => 'CodeIgniterInstaller',
'concrete5' => 'Concrete5Installer',
'craft' => 'CraftInstaller',
'croogo' => 'CroogoInstaller',
'dframe' => 'DframeInstaller',
'dokuwiki' => 'DokuWikiInstaller',
'dolibarr' => 'DolibarrInstaller',
'decibel' => 'DecibelInstaller',
'drupal' => 'DrupalInstaller',
'elgg' => 'ElggInstaller',
'eliasis' => 'EliasisInstaller',
'ee3' => 'ExpressionEngineInstaller',
'ee2' => 'ExpressionEngineInstaller',
'ezplatform' => 'EzPlatformInstaller',
'fuel' => 'FuelInstaller',
'fuelphp' => 'FuelphpInstaller',
'grav' => 'GravInstaller',
'hurad' => 'HuradInstaller',
'imagecms' => 'ImageCMSInstaller',
'itop' => 'ItopInstaller',
'joomla' => 'JoomlaInstaller',
'kanboard' => 'KanboardInstaller',
'kirby' => 'KirbyInstaller',
'known' => 'KnownInstaller',
'kodicms' => 'KodiCMSInstaller',
'kohana' => 'KohanaInstaller',
'lms' => 'LanManagementSystemInstaller',
'laravel' => 'LaravelInstaller',
'lavalite' => 'LavaLiteInstaller',
'lithium' => 'LithiumInstaller',
'magento' => 'MagentoInstaller',
'majima' => 'MajimaInstaller',
'mantisbt' => 'MantisBTInstaller',
'mako' => 'MakoInstaller',
'maya' => 'MayaInstaller',
'mautic' => 'MauticInstaller',
'mediawiki' => 'MediaWikiInstaller',
'microweber' => 'MicroweberInstaller',
'modulework' => 'MODULEWorkInstaller',
'modx' => 'ModxInstaller',
'modxevo' => 'MODXEvoInstaller',
'moodle' => 'MoodleInstaller',
'october' => 'OctoberInstaller',
'ontowiki' => 'OntoWikiInstaller',
'oxid' => 'OxidInstaller',
'osclass' => 'OsclassInstaller',
'pxcms' => 'PxcmsInstaller',
'phpbb' => 'PhpBBInstaller',
'pimcore' => 'PimcoreInstaller',
'piwik' => 'PiwikInstaller',
'plentymarkets'=> 'PlentymarketsInstaller',
'ppi' => 'PPIInstaller',
'puppet' => 'PuppetInstaller',
'radphp' => 'RadPHPInstaller',
'phifty' => 'PhiftyInstaller',
'porto' => 'PortoInstaller',
'redaxo' => 'RedaxoInstaller',
'redaxo5' => 'Redaxo5Installer',
'reindex' => 'ReIndexInstaller',
'roundcube' => 'RoundcubeInstaller',
'shopware' => 'ShopwareInstaller',
'sitedirect' => 'SiteDirectInstaller',
'silverstripe' => 'SilverStripeInstaller',
'smf' => 'SMFInstaller',
'sydes' => 'SyDESInstaller',
'sylius' => 'SyliusInstaller',
'symfony1' => 'Symfony1Installer',
'tao' => 'TaoInstaller',
'thelia' => 'TheliaInstaller',
'tusk' => 'TuskInstaller',
'typo3-cms' => 'TYPO3CmsInstaller',
'typo3-flow' => 'TYPO3FlowInstaller',
'userfrosting' => 'UserFrostingInstaller',
'vanilla' => 'VanillaInstaller',
'whmcs' => 'WHMCSInstaller',
'wolfcms' => 'WolfCMSInstaller',
'wordpress' => 'WordPressInstaller',
'yawik' => 'YawikInstaller',
'zend' => 'ZendInstaller',
'zikula' => 'ZikulaInstaller',
'prestashop' => 'PrestashopInstaller'
);
/**
* Installer constructor.
*
* Disables installers specified in main composer extra installer-disable
* list
*
* @param IOInterface $io
* @param Composer $composer
* @param string $type
* @param Filesystem|null $filesystem
* @param BinaryInstaller|null $binaryInstaller
*/
public function __construct(
IOInterface $io,
Composer $composer,
$type = 'library',
Filesystem $filesystem = null,
BinaryInstaller $binaryInstaller = null
) {
parent::__construct($io, $composer, $type, $filesystem,
$binaryInstaller);
$this->removeDisabledInstallers();
}
/**
* {@inheritDoc}
*/
public function getInstallPath(PackageInterface $package)
{
$type = $package->getType();
$frameworkType = $this->findFrameworkType($type);
if ($frameworkType === false) {
throw new \InvalidArgumentException(
'Sorry the package type of this package is not yet supported.'
);
}
$class = 'Composer\\Installers\\' . $this->supportedTypes[$frameworkType];
$installer = new $class($package, $this->composer, $this->getIO());
return $installer->getInstallPath($package, $frameworkType);
}
public function uninstall(InstalledRepositoryInterface $repo, PackageInterface $package)
{
parent::uninstall($repo, $package);
$installPath = $this->getPackageBasePath($package);
$this->io->write(sprintf('Deleting %s - %s', $installPath, !file_exists($installPath) ? '<comment>deleted</comment>' : '<error>not deleted</error>'));
}
/**
* {@inheritDoc}
*/
public function supports($packageType)
{
$frameworkType = $this->findFrameworkType($packageType);
if ($frameworkType === false) {
return false;
}
$locationPattern = $this->getLocationPattern($frameworkType);
return preg_match('#' . $frameworkType . '-' . $locationPattern . '#', $packageType, $matches) === 1;
}
/**
* Finds a supported framework type if it exists and returns it
*
* @param string $type
* @return string
*/
protected function findFrameworkType($type)
{
$frameworkType = false;
krsort($this->supportedTypes);
foreach ($this->supportedTypes as $key => $val) {
if ($key === substr($type, 0, strlen($key))) {
$frameworkType = substr($type, 0, strlen($key));
break;
}
}
return $frameworkType;
}
/**
* Get the second part of the regular expression to check for support of a
* package type
*
* @param string $frameworkType
* @return string
*/
protected function getLocationPattern($frameworkType)
{
$pattern = false;
if (!empty($this->supportedTypes[$frameworkType])) {
$frameworkClass = 'Composer\\Installers\\' . $this->supportedTypes[$frameworkType];
/** @var BaseInstaller $framework */
$framework = new $frameworkClass(null, $this->composer, $this->getIO());
$locations = array_keys($framework->getLocations());
$pattern = $locations ? '(' . implode('|', $locations) . ')' : false;
}
return $pattern ? : '(\w+)';
}
/**
* Get I/O object
*
* @return IOInterface
*/
private function getIO()
{
return $this->io;
}
/**
* Look for installers set to be disabled in composer's extra config and
* remove them from the list of supported installers.
*
* Globals:
* - true, "all", and "*" - disable all installers.
* - false - enable all installers (useful with
* wikimedia/composer-merge-plugin or similar)
*
* @return void
*/
protected function removeDisabledInstallers()
{
$extra = $this->composer->getPackage()->getExtra();
if (!isset($extra['installer-disable']) || $extra['installer-disable'] === false) {
// No installers are disabled
return;
}
// Get installers to disable
$disable = $extra['installer-disable'];
// Ensure $disabled is an array
if (!is_array($disable)) {
$disable = array($disable);
}
// Check which installers should be disabled
$all = array(true, "all", "*");
$intersect = array_intersect($all, $disable);
if (!empty($intersect)) {
// Disable all installers
$this->supportedTypes = array();
} else {
// Disable specified installers
foreach ($disable as $key => $installer) {
if (is_string($installer) && key_exists($installer, $this->supportedTypes)) {
unset($this->supportedTypes[$installer]);
}
}
}
}
}

View File

@ -0,0 +1,9 @@
<?php
namespace Composer\Installers;
class ItopInstaller extends BaseInstaller
{
protected $locations = array(
'extension' => 'extensions/{$name}/',
);
}

View File

@ -0,0 +1,15 @@
<?php
namespace Composer\Installers;
class JoomlaInstaller extends BaseInstaller
{
protected $locations = array(
'component' => 'components/{$name}/',
'module' => 'modules/{$name}/',
'template' => 'templates/{$name}/',
'plugin' => 'plugins/{$name}/',
'library' => 'libraries/{$name}/',
);
// TODO: Add inflector for mod_ and com_ names
}

View File

@ -0,0 +1,18 @@
<?php
namespace Composer\Installers;
/**
*
* Installer for kanboard plugins
*
* kanboard.net
*
* Class KanboardInstaller
* @package Composer\Installers
*/
class KanboardInstaller extends BaseInstaller
{
protected $locations = array(
'plugin' => 'plugins/{$name}/',
);
}

View File

@ -0,0 +1,11 @@
<?php
namespace Composer\Installers;
class KirbyInstaller extends BaseInstaller
{
protected $locations = array(
'plugin' => 'site/plugins/{$name}/',
'field' => 'site/fields/{$name}/',
'tag' => 'site/tags/{$name}/'
);
}

View File

@ -0,0 +1,11 @@
<?php
namespace Composer\Installers;
class KnownInstaller extends BaseInstaller
{
protected $locations = array(
'plugin' => 'IdnoPlugins/{$name}/',
'theme' => 'Themes/{$name}/',
'console' => 'ConsolePlugins/{$name}/',
);
}

View File

@ -0,0 +1,10 @@
<?php
namespace Composer\Installers;
class KodiCMSInstaller extends BaseInstaller
{
protected $locations = array(
'plugin' => 'cms/plugins/{$name}/',
'media' => 'cms/media/vendor/{$name}/'
);
}

View File

@ -0,0 +1,9 @@
<?php
namespace Composer\Installers;
class KohanaInstaller extends BaseInstaller
{
protected $locations = array(
'module' => 'modules/{$name}/',
);
}

View File

@ -0,0 +1,27 @@
<?php
namespace Composer\Installers;
class LanManagementSystemInstaller extends BaseInstaller
{
protected $locations = array(
'plugin' => 'plugins/{$name}/',
'template' => 'templates/{$name}/',
'document-template' => 'documents/templates/{$name}/',
'userpanel-module' => 'userpanel/modules/{$name}/',
);
/**
* Format package name to CamelCase
*/
public function inflectPackageVars($vars)
{
$vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name']));
$vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
$vars['name'] = str_replace(' ', '', ucwords($vars['name']));
return $vars;
}
}

View File

@ -0,0 +1,9 @@
<?php
namespace Composer\Installers;
class LaravelInstaller extends BaseInstaller
{
protected $locations = array(
'library' => 'libraries/{$name}/',
);
}

View File

@ -0,0 +1,10 @@
<?php
namespace Composer\Installers;
class LavaLiteInstaller extends BaseInstaller
{
protected $locations = array(
'package' => 'packages/{$vendor}/{$name}/',
'theme' => 'public/themes/{$name}/',
);
}

View File

@ -0,0 +1,10 @@
<?php
namespace Composer\Installers;
class LithiumInstaller extends BaseInstaller
{
protected $locations = array(
'library' => 'libraries/{$name}/',
'source' => 'libraries/_source/{$name}/',
);
}

View File

@ -0,0 +1,9 @@
<?php
namespace Composer\Installers;
class MODULEWorkInstaller extends BaseInstaller
{
protected $locations = array(
'module' => 'modules/{$name}/',
);
}

View File

@ -0,0 +1,16 @@
<?php
namespace Composer\Installers;
/**
* An installer to handle MODX Evolution specifics when installing packages.
*/
class MODXEvoInstaller extends BaseInstaller
{
protected $locations = array(
'snippet' => 'assets/snippets/{$name}/',
'plugin' => 'assets/plugins/{$name}/',
'module' => 'assets/modules/{$name}/',
'template' => 'assets/templates/{$name}/',
'lib' => 'assets/lib/{$name}/'
);
}

View File

@ -0,0 +1,11 @@
<?php
namespace Composer\Installers;
class MagentoInstaller extends BaseInstaller
{
protected $locations = array(
'theme' => 'app/design/frontend/{$name}/',
'skin' => 'skin/frontend/default/{$name}/',
'library' => 'lib/{$name}/',
);
}

View File

@ -0,0 +1,37 @@
<?php
namespace Composer\Installers;
/**
* Plugin/theme installer for majima
* @author David Neustadt
*/
class MajimaInstaller extends BaseInstaller
{
protected $locations = array(
'plugin' => 'plugins/{$name}/',
);
/**
* Transforms the names
* @param array $vars
* @return array
*/
public function inflectPackageVars($vars)
{
return $this->correctPluginName($vars);
}
/**
* Change hyphenated names to camelcase
* @param array $vars
* @return array
*/
private function correctPluginName($vars)
{
$camelCasedName = preg_replace_callback('/(-[a-z])/', function ($matches) {
return strtoupper($matches[0][1]);
}, $vars['name']);
$vars['name'] = ucfirst($camelCasedName);
return $vars;
}
}

View File

@ -0,0 +1,9 @@
<?php
namespace Composer\Installers;
class MakoInstaller extends BaseInstaller
{
protected $locations = array(
'package' => 'app/packages/{$name}/',
);
}

View File

@ -0,0 +1,23 @@
<?php
namespace Composer\Installers;
use Composer\DependencyResolver\Pool;
class MantisBTInstaller extends BaseInstaller
{
protected $locations = array(
'plugin' => 'plugins/{$name}/',
);
/**
* Format package name to CamelCase
*/
public function inflectPackageVars($vars)
{
$vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name']));
$vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
$vars['name'] = str_replace(' ', '', ucwords($vars['name']));
return $vars;
}
}

View File

@ -0,0 +1,25 @@
<?php
namespace Composer\Installers;
class MauticInstaller extends BaseInstaller
{
protected $locations = array(
'plugin' => 'plugins/{$name}/',
'theme' => 'themes/{$name}/',
);
/**
* Format package name of mautic-plugins to CamelCase
*/
public function inflectPackageVars($vars)
{
if ($vars['type'] == 'mautic-plugin') {
$vars['name'] = preg_replace_callback('/(-[a-z])/', function ($matches) {
return strtoupper($matches[0][1]);
}, ucfirst($vars['name']));
}
return $vars;
}
}

View File

@ -0,0 +1,33 @@
<?php
namespace Composer\Installers;
class MayaInstaller extends BaseInstaller
{
protected $locations = array(
'module' => 'modules/{$name}/',
);
/**
* Format package name.
*
* For package type maya-module, cut off a trailing '-module' if present.
*
*/
public function inflectPackageVars($vars)
{
if ($vars['type'] === 'maya-module') {
return $this->inflectModuleVars($vars);
}
return $vars;
}
protected function inflectModuleVars($vars)
{
$vars['name'] = preg_replace('/-module$/', '', $vars['name']);
$vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
$vars['name'] = str_replace(' ', '', ucwords($vars['name']));
return $vars;
}
}

View File

@ -0,0 +1,51 @@
<?php
namespace Composer\Installers;
class MediaWikiInstaller extends BaseInstaller
{
protected $locations = array(
'core' => 'core/',
'extension' => 'extensions/{$name}/',
'skin' => 'skins/{$name}/',
);
/**
* Format package name.
*
* For package type mediawiki-extension, cut off a trailing '-extension' if present and transform
* to CamelCase keeping existing uppercase chars.
*
* For package type mediawiki-skin, cut off a trailing '-skin' if present.
*
*/
public function inflectPackageVars($vars)
{
if ($vars['type'] === 'mediawiki-extension') {
return $this->inflectExtensionVars($vars);
}
if ($vars['type'] === 'mediawiki-skin') {
return $this->inflectSkinVars($vars);
}
return $vars;
}
protected function inflectExtensionVars($vars)
{
$vars['name'] = preg_replace('/-extension$/', '', $vars['name']);
$vars['name'] = str_replace('-', ' ', $vars['name']);
$vars['name'] = str_replace(' ', '', ucwords($vars['name']));
return $vars;
}
protected function inflectSkinVars($vars)
{
$vars['name'] = preg_replace('/-skin$/', '', $vars['name']);
return $vars;
}
}

View File

@ -0,0 +1,119 @@
<?php
namespace Composer\Installers;
class MicroweberInstaller extends BaseInstaller
{
protected $locations = array(
'module' => 'userfiles/modules/{$install_item_dir}/',
'module-skin' => 'userfiles/modules/{$install_item_dir}/templates/',
'template' => 'userfiles/templates/{$install_item_dir}/',
'element' => 'userfiles/elements/{$install_item_dir}/',
'vendor' => 'vendor/{$install_item_dir}/',
'components' => 'components/{$install_item_dir}/'
);
/**
* Format package name.
*
* For package type microweber-module, cut off a trailing '-module' if present
*
* For package type microweber-template, cut off a trailing '-template' if present.
*
*/
public function inflectPackageVars($vars)
{
if ($this->package->getTargetDir()) {
$vars['install_item_dir'] = $this->package->getTargetDir();
} else {
$vars['install_item_dir'] = $vars['name'];
if ($vars['type'] === 'microweber-template') {
return $this->inflectTemplateVars($vars);
}
if ($vars['type'] === 'microweber-templates') {
return $this->inflectTemplatesVars($vars);
}
if ($vars['type'] === 'microweber-core') {
return $this->inflectCoreVars($vars);
}
if ($vars['type'] === 'microweber-adapter') {
return $this->inflectCoreVars($vars);
}
if ($vars['type'] === 'microweber-module') {
return $this->inflectModuleVars($vars);
}
if ($vars['type'] === 'microweber-modules') {
return $this->inflectModulesVars($vars);
}
if ($vars['type'] === 'microweber-skin') {
return $this->inflectSkinVars($vars);
}
if ($vars['type'] === 'microweber-element' or $vars['type'] === 'microweber-elements') {
return $this->inflectElementVars($vars);
}
}
return $vars;
}
protected function inflectTemplateVars($vars)
{
$vars['install_item_dir'] = preg_replace('/-template$/', '', $vars['install_item_dir']);
$vars['install_item_dir'] = preg_replace('/template-$/', '', $vars['install_item_dir']);
return $vars;
}
protected function inflectTemplatesVars($vars)
{
$vars['install_item_dir'] = preg_replace('/-templates$/', '', $vars['install_item_dir']);
$vars['install_item_dir'] = preg_replace('/templates-$/', '', $vars['install_item_dir']);
return $vars;
}
protected function inflectCoreVars($vars)
{
$vars['install_item_dir'] = preg_replace('/-providers$/', '', $vars['install_item_dir']);
$vars['install_item_dir'] = preg_replace('/-provider$/', '', $vars['install_item_dir']);
$vars['install_item_dir'] = preg_replace('/-adapter$/', '', $vars['install_item_dir']);
return $vars;
}
protected function inflectModuleVars($vars)
{
$vars['install_item_dir'] = preg_replace('/-module$/', '', $vars['install_item_dir']);
$vars['install_item_dir'] = preg_replace('/module-$/', '', $vars['install_item_dir']);
return $vars;
}
protected function inflectModulesVars($vars)
{
$vars['install_item_dir'] = preg_replace('/-modules$/', '', $vars['install_item_dir']);
$vars['install_item_dir'] = preg_replace('/modules-$/', '', $vars['install_item_dir']);
return $vars;
}
protected function inflectSkinVars($vars)
{
$vars['install_item_dir'] = preg_replace('/-skin$/', '', $vars['install_item_dir']);
$vars['install_item_dir'] = preg_replace('/skin-$/', '', $vars['install_item_dir']);
return $vars;
}
protected function inflectElementVars($vars)
{
$vars['install_item_dir'] = preg_replace('/-elements$/', '', $vars['install_item_dir']);
$vars['install_item_dir'] = preg_replace('/elements-$/', '', $vars['install_item_dir']);
$vars['install_item_dir'] = preg_replace('/-element$/', '', $vars['install_item_dir']);
$vars['install_item_dir'] = preg_replace('/element-$/', '', $vars['install_item_dir']);
return $vars;
}
}

View File

@ -0,0 +1,12 @@
<?php
namespace Composer\Installers;
/**
* An installer to handle MODX specifics when installing packages.
*/
class ModxInstaller extends BaseInstaller
{
protected $locations = array(
'extra' => 'core/packages/{$name}/'
);
}

View File

@ -0,0 +1,58 @@
<?php
namespace Composer\Installers;
class MoodleInstaller extends BaseInstaller
{
protected $locations = array(
'mod' => 'mod/{$name}/',
'admin_report' => 'admin/report/{$name}/',
'atto' => 'lib/editor/atto/plugins/{$name}/',
'tool' => 'admin/tool/{$name}/',
'assignment' => 'mod/assignment/type/{$name}/',
'assignsubmission' => 'mod/assign/submission/{$name}/',
'assignfeedback' => 'mod/assign/feedback/{$name}/',
'auth' => 'auth/{$name}/',
'availability' => 'availability/condition/{$name}/',
'block' => 'blocks/{$name}/',
'booktool' => 'mod/book/tool/{$name}/',
'cachestore' => 'cache/stores/{$name}/',
'cachelock' => 'cache/locks/{$name}/',
'calendartype' => 'calendar/type/{$name}/',
'format' => 'course/format/{$name}/',
'coursereport' => 'course/report/{$name}/',
'customcertelement' => 'mod/customcert/element/{$name}/',
'datafield' => 'mod/data/field/{$name}/',
'datapreset' => 'mod/data/preset/{$name}/',
'editor' => 'lib/editor/{$name}/',
'enrol' => 'enrol/{$name}/',
'filter' => 'filter/{$name}/',
'gradeexport' => 'grade/export/{$name}/',
'gradeimport' => 'grade/import/{$name}/',
'gradereport' => 'grade/report/{$name}/',
'gradingform' => 'grade/grading/form/{$name}/',
'local' => 'local/{$name}/',
'logstore' => 'admin/tool/log/store/{$name}/',
'ltisource' => 'mod/lti/source/{$name}/',
'ltiservice' => 'mod/lti/service/{$name}/',
'message' => 'message/output/{$name}/',
'mnetservice' => 'mnet/service/{$name}/',
'plagiarism' => 'plagiarism/{$name}/',
'portfolio' => 'portfolio/{$name}/',
'qbehaviour' => 'question/behaviour/{$name}/',
'qformat' => 'question/format/{$name}/',
'qtype' => 'question/type/{$name}/',
'quizaccess' => 'mod/quiz/accessrule/{$name}/',
'quiz' => 'mod/quiz/report/{$name}/',
'report' => 'report/{$name}/',
'repository' => 'repository/{$name}/',
'scormreport' => 'mod/scorm/report/{$name}/',
'search' => 'search/engine/{$name}/',
'theme' => 'theme/{$name}/',
'tinymce' => 'lib/editor/tinymce/plugins/{$name}/',
'profilefield' => 'user/profile/field/{$name}/',
'webservice' => 'webservice/{$name}/',
'workshopallocation' => 'mod/workshop/allocation/{$name}/',
'workshopeval' => 'mod/workshop/eval/{$name}/',
'workshopform' => 'mod/workshop/form/{$name}/'
);
}

View File

@ -0,0 +1,47 @@
<?php
namespace Composer\Installers;
class OctoberInstaller extends BaseInstaller
{
protected $locations = array(
'module' => 'modules/{$name}/',
'plugin' => 'plugins/{$vendor}/{$name}/',
'theme' => 'themes/{$name}/'
);
/**
* Format package name.
*
* For package type october-plugin, cut off a trailing '-plugin' if present.
*
* For package type october-theme, cut off a trailing '-theme' if present.
*
*/
public function inflectPackageVars($vars)
{
if ($vars['type'] === 'october-plugin') {
return $this->inflectPluginVars($vars);
}
if ($vars['type'] === 'october-theme') {
return $this->inflectThemeVars($vars);
}
return $vars;
}
protected function inflectPluginVars($vars)
{
$vars['name'] = preg_replace('/^oc-|-plugin$/', '', $vars['name']);
$vars['vendor'] = preg_replace('/[^a-z0-9_]/i', '', $vars['vendor']);
return $vars;
}
protected function inflectThemeVars($vars)
{
$vars['name'] = preg_replace('/^oc-|-theme$/', '', $vars['name']);
return $vars;
}
}

View File

@ -0,0 +1,24 @@
<?php
namespace Composer\Installers;
class OntoWikiInstaller extends BaseInstaller
{
protected $locations = array(
'extension' => 'extensions/{$name}/',
'theme' => 'extensions/themes/{$name}/',
'translation' => 'extensions/translations/{$name}/',
);
/**
* Format package name to lower case and remove ".ontowiki" suffix
*/
public function inflectPackageVars($vars)
{
$vars['name'] = strtolower($vars['name']);
$vars['name'] = preg_replace('/.ontowiki$/', '', $vars['name']);
$vars['name'] = preg_replace('/-theme$/', '', $vars['name']);
$vars['name'] = preg_replace('/-translation$/', '', $vars['name']);
return $vars;
}
}

View File

@ -0,0 +1,14 @@
<?php
namespace Composer\Installers;
class OsclassInstaller extends BaseInstaller
{
protected $locations = array(
'plugin' => 'oc-content/plugins/{$name}/',
'theme' => 'oc-content/themes/{$name}/',
'language' => 'oc-content/languages/{$name}/',
);
}

View File

@ -0,0 +1,59 @@
<?php
namespace Composer\Installers;
use Composer\Package\PackageInterface;
class OxidInstaller extends BaseInstaller
{
const VENDOR_PATTERN = '/^modules\/(?P<vendor>.+)\/.+/';
protected $locations = array(
'module' => 'modules/{$name}/',
'theme' => 'application/views/{$name}/',
'out' => 'out/{$name}/',
);
/**
* getInstallPath
*
* @param PackageInterface $package
* @param string $frameworkType
* @return void
*/
public function getInstallPath(PackageInterface $package, $frameworkType = '')
{
$installPath = parent::getInstallPath($package, $frameworkType);
$type = $this->package->getType();
if ($type === 'oxid-module') {
$this->prepareVendorDirectory($installPath);
}
return $installPath;
}
/**
* prepareVendorDirectory
*
* Makes sure there is a vendormetadata.php file inside
* the vendor folder if there is a vendor folder.
*
* @param string $installPath
* @return void
*/
protected function prepareVendorDirectory($installPath)
{
$matches = '';
$hasVendorDirectory = preg_match(self::VENDOR_PATTERN, $installPath, $matches);
if (!$hasVendorDirectory) {
return;
}
$vendorDirectory = $matches['vendor'];
$vendorPath = getcwd() . '/modules/' . $vendorDirectory;
if (!file_exists($vendorPath)) {
mkdir($vendorPath, 0755, true);
}
$vendorMetaDataPath = $vendorPath . '/vendormetadata.php';
touch($vendorMetaDataPath);
}
}

View File

@ -0,0 +1,9 @@
<?php
namespace Composer\Installers;
class PPIInstaller extends BaseInstaller
{
protected $locations = array(
'module' => 'modules/{$name}/',
);
}

View File

@ -0,0 +1,11 @@
<?php
namespace Composer\Installers;
class PhiftyInstaller extends BaseInstaller
{
protected $locations = array(
'bundle' => 'bundles/{$name}/',
'library' => 'libraries/{$name}/',
'framework' => 'frameworks/{$name}/',
);
}

View File

@ -0,0 +1,11 @@
<?php
namespace Composer\Installers;
class PhpBBInstaller extends BaseInstaller
{
protected $locations = array(
'extension' => 'ext/{$vendor}/{$name}/',
'language' => 'language/{$name}/',
'style' => 'styles/{$name}/',
);
}

View File

@ -0,0 +1,21 @@
<?php
namespace Composer\Installers;
class PimcoreInstaller extends BaseInstaller
{
protected $locations = array(
'plugin' => 'plugins/{$name}/',
);
/**
* Format package name to CamelCase
*/
public function inflectPackageVars($vars)
{
$vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name']));
$vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
$vars['name'] = str_replace(' ', '', ucwords($vars['name']));
return $vars;
}
}

View File

@ -0,0 +1,32 @@
<?php
namespace Composer\Installers;
/**
* Class PiwikInstaller
*
* @package Composer\Installers
*/
class PiwikInstaller extends BaseInstaller
{
/**
* @var array
*/
protected $locations = array(
'plugin' => 'plugins/{$name}/',
);
/**
* Format package name to CamelCase
* @param array $vars
*
* @return array
*/
public function inflectPackageVars($vars)
{
$vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name']));
$vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
$vars['name'] = str_replace(' ', '', ucwords($vars['name']));
return $vars;
}
}

View File

@ -0,0 +1,29 @@
<?php
namespace Composer\Installers;
class PlentymarketsInstaller extends BaseInstaller
{
protected $locations = array(
'plugin' => '{$name}/'
);
/**
* Remove hyphen, "plugin" and format to camelcase
* @param array $vars
*
* @return array
*/
public function inflectPackageVars($vars)
{
$vars['name'] = explode("-", $vars['name']);
foreach ($vars['name'] as $key => $name) {
$vars['name'][$key] = ucfirst($vars['name'][$key]);
if (strcasecmp($name, "Plugin") == 0) {
unset($vars['name'][$key]);
}
}
$vars['name'] = implode("",$vars['name']);
return $vars;
}
}

View File

@ -0,0 +1,27 @@
<?php
namespace Composer\Installers;
use Composer\Composer;
use Composer\IO\IOInterface;
use Composer\Plugin\PluginInterface;
class Plugin implements PluginInterface
{
private $installer;
public function activate(Composer $composer, IOInterface $io)
{
$this->installer = new Installer($io, $composer);
$composer->getInstallationManager()->addInstaller($this->installer);
}
public function deactivate(Composer $composer, IOInterface $io)
{
$composer->getInstallationManager()->removeInstaller($this->installer);
}
public function uninstall(Composer $composer, IOInterface $io)
{
}
}

View File

@ -0,0 +1,9 @@
<?php
namespace Composer\Installers;
class PortoInstaller extends BaseInstaller
{
protected $locations = array(
'container' => 'app/Containers/{$name}/',
);
}

View File

@ -0,0 +1,10 @@
<?php
namespace Composer\Installers;
class PrestashopInstaller extends BaseInstaller
{
protected $locations = array(
'module' => 'modules/{$name}/',
'theme' => 'themes/{$name}/',
);
}

View File

@ -0,0 +1,11 @@
<?php
namespace Composer\Installers;
class PuppetInstaller extends BaseInstaller
{
protected $locations = array(
'module' => 'modules/{$name}/',
);
}

View File

@ -0,0 +1,63 @@
<?php
namespace Composer\Installers;
class PxcmsInstaller extends BaseInstaller
{
protected $locations = array(
'module' => 'app/Modules/{$name}/',
'theme' => 'themes/{$name}/',
);
/**
* Format package name.
*
* @param array $vars
*
* @return array
*/
public function inflectPackageVars($vars)
{
if ($vars['type'] === 'pxcms-module') {
return $this->inflectModuleVars($vars);
}
if ($vars['type'] === 'pxcms-theme') {
return $this->inflectThemeVars($vars);
}
return $vars;
}
/**
* For package type pxcms-module, cut off a trailing '-plugin' if present.
*
* return string
*/
protected function inflectModuleVars($vars)
{
$vars['name'] = str_replace('pxcms-', '', $vars['name']); // strip out pxcms- just incase (legacy)
$vars['name'] = str_replace('module-', '', $vars['name']); // strip out module-
$vars['name'] = preg_replace('/-module$/', '', $vars['name']); // strip out -module
$vars['name'] = str_replace('-', '_', $vars['name']); // make -'s be _'s
$vars['name'] = ucwords($vars['name']); // make module name camelcased
return $vars;
}
/**
* For package type pxcms-module, cut off a trailing '-plugin' if present.
*
* return string
*/
protected function inflectThemeVars($vars)
{
$vars['name'] = str_replace('pxcms-', '', $vars['name']); // strip out pxcms- just incase (legacy)
$vars['name'] = str_replace('theme-', '', $vars['name']); // strip out theme-
$vars['name'] = preg_replace('/-theme$/', '', $vars['name']); // strip out -theme
$vars['name'] = str_replace('-', '_', $vars['name']); // make -'s be _'s
$vars['name'] = ucwords($vars['name']); // make module name camelcased
return $vars;
}
}

Some files were not shown because too many files have changed in this diff Show More