from server 18.01

This commit is contained in:
Shohrat 2023-01-18 05:02:37 +00:00
parent 1bd6c22649
commit d787c6a56b
444 changed files with 47204 additions and 16149 deletions

View File

@ -1,5 +1,5 @@
<IfModule mod_rewrite.c>
DirectoryIndex index.php
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>
@ -16,7 +16,11 @@
## Uncomment following lines to force HTTPS.
##
# RewriteCond %{HTTPS} off
# RewriteRule (.*) https://%{SERVER_NAME}/$1 [L,R=301]
# RewriteRule (.*) http://%{SERVER_NAME}/$1 [L,R=301]
RewriteCond %{HTTPS} !off [OR]
RewriteCond %{HTTP_HOST} ^www\. [NC]
RewriteRule ^ http://sapalymahabat.com.tm%{REQUEST_URI} [R=302,L,NE]
##
## Black listed folders

View File

@ -57,9 +57,9 @@ return [
'engine' => 'InnoDB',
'host' => 'localhost',
'port' => 3306,
'database' => 'october2',
'username' => 'root',
'password' => 'bt110226',
'database' => 'sapaly_october',
'username' => 'sapaly',
'password' => '22MOcP6^I#8tI5ovcXluXDT#%vWC^CtsFvKHOygi8TMnzaMuLYx@123',
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',

146
config/database.php.save Normal file
View File

@ -0,0 +1,146 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| PDO Fetch Style
|--------------------------------------------------------------------------
|
| By default, database results will be returned as instances of the PHP
| stdClass object; however, you may desire to retrieve records in an
| array format for simplicity. Here you can tweak the fetch style.
|
*/
'fetch' => PDO::FETCH_CLASS,
/*
|--------------------------------------------------------------------------
| Default Database Connection Name
|--------------------------------------------------------------------------
|
| Here you may specify which of the database connections below you wish
| to use as your default connection for all database work. Of course
| you may use many connections at once using the Database library.
|
*/
'default' => 'mysql',
/*
|--------------------------------------------------------------------------
| Database Connections
|--------------------------------------------------------------------------
|
| Here are each of the database connections setup for your application.
| Of course, examples of configuring each database platform that is
| supported by Laravel is shown below to make development simple.
|
|
| All database work in Laravel is done through the PHP PDO facilities
| so make sure you have the driver for your particular database of
| choice installed on your machine before you begin development.
|
*/
'connections' => [
'sqlite' => [
'driver' => 'sqlite',
'database' => 'storage/database.sqlite',
'prefix' => '',
],
'mysql' => [
'driver' => 'mysql',
'engine' => 'InnoDB',
'host' => 'localhost',
'port' => 3306,
'database' => 'sapaly_october',
'username' => 'sapaly',
'password' => '',
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'varcharmax' => 191,
],
'pgsql' => [
'driver' => 'pgsql',
'host' => 'localhost',
'port' => 5432,
'database' => 'database',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
'prefix' => '',
'schema' => 'public',
],
'sqlsrv' => [
'driver' => 'sqlsrv',
'host' => 'localhost',
'port' => 1433,
'database' => 'database',
'username' => 'root',
'password' => '',
'prefix' => '',
],
],
/*
|--------------------------------------------------------------------------
| Migration Repository Table
|--------------------------------------------------------------------------
|
| This table keeps track of all the migrations that have already run for
| your application. Using this information, we can determine which of
| the migrations on disk have not actually be run in the databases.
|
*/
'migrations' => 'migrations',
/*
|--------------------------------------------------------------------------
| Redis Databases
|--------------------------------------------------------------------------
|
| Redis is an open source, fast, and advanced key-value store that also
| provides a richer set of commands than a typical key-value systems
| such as APC or Memcached. Laravel makes it easy to dig right in.
|
*/
'redis' => [
'cluster' => false,
'default' => [
'host' => '127.0.0.1',
'password' => null,
'port' => 6379,
'database' => 0,
],
],
/*
|--------------------------------------------------------------------------
| Use DB configuration for testing
|--------------------------------------------------------------------------
|
| When running plugin tests OctoberCMS by default uses SQLite in memory.
| You can override this behavior by setting `useConfigForTesting` to true.
|
| After that OctoberCMS will take DB parameters from the config.
| If file `/config/testing/database.php` exists, config will be read from it,
| but remember that when not specified it will use parameters specified in
| `/config/database.php`.
|
*/
'useConfigForTesting' => false,
];

2454
october2.sql Normal file

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,18 @@
<?php namespace Akami\Coffe30\Controllers;
use Backend\Classes\Controller;
use BackendMenu;
class Comment extends Controller
{
public $implement = [ 'Backend\Behaviors\ListController', 'Backend\Behaviors\FormController' ];
public $listConfig = 'config_list.yaml';
public $formConfig = 'config_form.yaml';
public function __construct()
{
parent::__construct();
BackendMenu::setContext('Akami.Coffe30', 'main-menu-item', 'side-menu-item2');
}
}

View File

@ -0,0 +1,18 @@
<?php namespace Akami\Coffe30\Controllers;
use Backend\Classes\Controller;
use BackendMenu;
class Partner extends Controller
{
public $implement = [ 'Backend\Behaviors\ListController', 'Backend\Behaviors\FormController' ];
public $listConfig = 'config_list.yaml';
public $formConfig = 'config_form.yaml';
public function __construct()
{
parent::__construct();
BackendMenu::setContext('Akami.Coffe30', 'main-menu-item', 'side-menu-item3');
}
}

View File

@ -0,0 +1,18 @@
<?php namespace Akami\Coffe30\Controllers;
use Backend\Classes\Controller;
use BackendMenu;
class Stores extends Controller
{
public $implement = [ 'Backend\Behaviors\ListController', 'Backend\Behaviors\FormController' ];
public $listConfig = 'config_list.yaml';
public $formConfig = 'config_form.yaml';
public function __construct()
{
parent::__construct();
BackendMenu::setContext('Akami.Coffe30', 'main-menu-item', 'side-menu-item4');
}
}

View File

@ -0,0 +1,18 @@
<div data-control="toolbar">
<a href="<?= Backend::url('akami/coffe30/comment/create') ?>" class="btn btn-primary oc-icon-plus"><?= e(trans('backend::lang.form.create')) ?></a>
<button
class="btn btn-default oc-icon-trash-o"
disabled="disabled"
onclick="$(this).data('request-data', {
checked: $('.control-list').listWidget('getChecked')
})"
data-request="onDelete"
data-request-confirm="<?= e(trans('backend::lang.list.delete_selected_confirm')) ?>"
data-trigger-action="enable"
data-trigger=".control-list input[type=checkbox]"
data-trigger-condition="checked"
data-request-success="$(this).prop('disabled', true)"
data-stripe-load-indicator>
<?= e(trans('backend::lang.list.delete_selected')) ?>
</button>
</div>

View File

@ -0,0 +1,10 @@
name: Comment
form: $/akami/coffe30/models/comment/fields.yaml
modelClass: Akami\Coffe30\Models\Comment
defaultRedirect: akami/coffe30/comment
create:
redirect: 'akami/coffe30/comment/update/:id'
redirectClose: akami/coffe30/comment
update:
redirect: akami/coffe30/comment
redirectClose: akami/coffe30/comment

View File

@ -0,0 +1,12 @@
list: $/akami/coffe30/models/comment/columns.yaml
modelClass: Akami\Coffe30\Models\Comment
title: Comment
noRecordsMessage: 'backend::lang.list.no_records'
showSetup: true
showCheckboxes: true
recordsPerPage: 20
toolbar:
buttons: list_toolbar
search:
prompt: 'backend::lang.list.search_prompt'
recordUrl: 'akami/coffe30/comment/update/:id'

View File

@ -0,0 +1,46 @@
<?php Block::put('breadcrumb') ?>
<ul>
<li><a href="<?= Backend::url('akami/coffe30/comment') ?>">Comment</a></li>
<li><?= e($this->pageTitle) ?></li>
</ul>
<?php Block::endPut() ?>
<?php if (!$this->fatalError): ?>
<?= Form::open(['class' => 'layout']) ?>
<div class="layout-row">
<?= $this->formRender() ?>
</div>
<div class="form-buttons">
<div class="loading-indicator-container">
<button
type="submit"
data-request="onSave"
data-hotkey="ctrl+s, cmd+s"
data-load-indicator="<?= e(trans('backend::lang.form.saving')) ?>"
class="btn btn-primary">
<?= e(trans('backend::lang.form.create')) ?>
</button>
<button
type="button"
data-request="onSave"
data-request-data="close:1"
data-hotkey="ctrl+enter, cmd+enter"
data-load-indicator="<?= e(trans('backend::lang.form.saving')) ?>"
class="btn btn-default">
<?= e(trans('backend::lang.form.create_and_close')) ?>
</button>
<span class="btn-text">
<?= e(trans('backend::lang.form.or')) ?> <a href="<?= Backend::url('akami/coffe30/comment') ?>"><?= e(trans('backend::lang.form.cancel')) ?></a>
</span>
</div>
</div>
<?= Form::close() ?>
<?php else: ?>
<p class="flash-message static error"><?= e(trans($this->fatalError)) ?></p>
<p><a href="<?= Backend::url('akami/coffe30/comment') ?>" class="btn btn-default"><?= e(trans('backend::lang.form.return_to_list')) ?></a></p>
<?php endif ?>

View File

@ -0,0 +1 @@
<?= $this->listRender() ?>

View File

@ -0,0 +1,22 @@
<?php Block::put('breadcrumb') ?>
<ul>
<li><a href="<?= Backend::url('akami/coffe30/comment') ?>">Comment</a></li>
<li><?= e($this->pageTitle) ?></li>
</ul>
<?php Block::endPut() ?>
<?php if (!$this->fatalError): ?>
<div class="form-preview">
<?= $this->formRenderPreview() ?>
</div>
<?php else: ?>
<p class="flash-message static error"><?= e($this->fatalError) ?></p>
<?php endif ?>
<p>
<a href="<?= Backend::url('akami/coffe30/comment') ?>" class="btn btn-default oc-icon-chevron-left">
<?= e(trans('backend::lang.form.return_to_list')) ?>
</a>
</p>

View File

@ -0,0 +1,54 @@
<?php Block::put('breadcrumb') ?>
<ul>
<li><a href="<?= Backend::url('akami/coffe30/comment') ?>">Comment</a></li>
<li><?= e($this->pageTitle) ?></li>
</ul>
<?php Block::endPut() ?>
<?php if (!$this->fatalError): ?>
<?= Form::open(['class' => 'layout']) ?>
<div class="layout-row">
<?= $this->formRender() ?>
</div>
<div class="form-buttons">
<div class="loading-indicator-container">
<button
type="submit"
data-request="onSave"
data-request-data="redirect:0"
data-hotkey="ctrl+s, cmd+s"
data-load-indicator="<?= e(trans('backend::lang.form.saving')) ?>"
class="btn btn-primary">
<?= e(trans('backend::lang.form.save')) ?>
</button>
<button
type="button"
data-request="onSave"
data-request-data="close:1"
data-hotkey="ctrl+enter, cmd+enter"
data-load-indicator="<?= e(trans('backend::lang.form.saving')) ?>"
class="btn btn-default">
<?= e(trans('backend::lang.form.save_and_close')) ?>
</button>
<button
type="button"
class="oc-icon-trash-o btn-icon danger pull-right"
data-request="onDelete"
data-load-indicator="<?= e(trans('backend::lang.form.deleting')) ?>"
data-request-confirm="<?= e(trans('backend::lang.form.confirm_delete')) ?>">
</button>
<span class="btn-text">
<?= e(trans('backend::lang.form.or')) ?> <a href="<?= Backend::url('akami/coffe30/comment') ?>"><?= e(trans('backend::lang.form.cancel')) ?></a>
</span>
</div>
</div>
<?= Form::close() ?>
<?php else: ?>
<p class="flash-message static error"><?= e(trans($this->fatalError)) ?></p>
<p><a href="<?= Backend::url('akami/coffe30/comment') ?>" class="btn btn-default"><?= e(trans('backend::lang.form.return_to_list')) ?></a></p>
<?php endif ?>

View File

@ -0,0 +1,18 @@
<div data-control="toolbar">
<a href="<?= Backend::url('akami/coffe30/partner/create') ?>" class="btn btn-primary oc-icon-plus"><?= e(trans('backend::lang.form.create')) ?></a>
<button
class="btn btn-default oc-icon-trash-o"
disabled="disabled"
onclick="$(this).data('request-data', {
checked: $('.control-list').listWidget('getChecked')
})"
data-request="onDelete"
data-request-confirm="<?= e(trans('backend::lang.list.delete_selected_confirm')) ?>"
data-trigger-action="enable"
data-trigger=".control-list input[type=checkbox]"
data-trigger-condition="checked"
data-request-success="$(this).prop('disabled', true)"
data-stripe-load-indicator>
<?= e(trans('backend::lang.list.delete_selected')) ?>
</button>
</div>

View File

@ -0,0 +1,10 @@
name: Partner
form: $/akami/coffe30/models/partner/fields.yaml
modelClass: Akami\Coffe30\Models\Partner
defaultRedirect: akami/coffe30/partner
create:
redirect: 'akami/coffe30/partner/update/:id'
redirectClose: akami/coffe30/partner
update:
redirect: akami/coffe30/partner
redirectClose: akami/coffe30/partner

View File

@ -0,0 +1,12 @@
list: $/akami/coffe30/models/partner/columns.yaml
modelClass: Akami\Coffe30\Models\Partner
title: Partner
noRecordsMessage: 'backend::lang.list.no_records'
showSetup: true
showCheckboxes: true
recordsPerPage: 20
toolbar:
buttons: list_toolbar
search:
prompt: 'backend::lang.list.search_prompt'
recordUrl: 'akami/coffe30/partner/update/:id'

View File

@ -0,0 +1,46 @@
<?php Block::put('breadcrumb') ?>
<ul>
<li><a href="<?= Backend::url('akami/coffe30/partner') ?>">Partner</a></li>
<li><?= e($this->pageTitle) ?></li>
</ul>
<?php Block::endPut() ?>
<?php if (!$this->fatalError): ?>
<?= Form::open(['class' => 'layout']) ?>
<div class="layout-row">
<?= $this->formRender() ?>
</div>
<div class="form-buttons">
<div class="loading-indicator-container">
<button
type="submit"
data-request="onSave"
data-hotkey="ctrl+s, cmd+s"
data-load-indicator="<?= e(trans('backend::lang.form.saving')) ?>"
class="btn btn-primary">
<?= e(trans('backend::lang.form.create')) ?>
</button>
<button
type="button"
data-request="onSave"
data-request-data="close:1"
data-hotkey="ctrl+enter, cmd+enter"
data-load-indicator="<?= e(trans('backend::lang.form.saving')) ?>"
class="btn btn-default">
<?= e(trans('backend::lang.form.create_and_close')) ?>
</button>
<span class="btn-text">
<?= e(trans('backend::lang.form.or')) ?> <a href="<?= Backend::url('akami/coffe30/partner') ?>"><?= e(trans('backend::lang.form.cancel')) ?></a>
</span>
</div>
</div>
<?= Form::close() ?>
<?php else: ?>
<p class="flash-message static error"><?= e(trans($this->fatalError)) ?></p>
<p><a href="<?= Backend::url('akami/coffe30/partner') ?>" class="btn btn-default"><?= e(trans('backend::lang.form.return_to_list')) ?></a></p>
<?php endif ?>

View File

@ -0,0 +1 @@
<?= $this->listRender() ?>

View File

@ -0,0 +1,22 @@
<?php Block::put('breadcrumb') ?>
<ul>
<li><a href="<?= Backend::url('akami/coffe30/partner') ?>">Partner</a></li>
<li><?= e($this->pageTitle) ?></li>
</ul>
<?php Block::endPut() ?>
<?php if (!$this->fatalError): ?>
<div class="form-preview">
<?= $this->formRenderPreview() ?>
</div>
<?php else: ?>
<p class="flash-message static error"><?= e($this->fatalError) ?></p>
<?php endif ?>
<p>
<a href="<?= Backend::url('akami/coffe30/partner') ?>" class="btn btn-default oc-icon-chevron-left">
<?= e(trans('backend::lang.form.return_to_list')) ?>
</a>
</p>

View File

@ -0,0 +1,54 @@
<?php Block::put('breadcrumb') ?>
<ul>
<li><a href="<?= Backend::url('akami/coffe30/partner') ?>">Partner</a></li>
<li><?= e($this->pageTitle) ?></li>
</ul>
<?php Block::endPut() ?>
<?php if (!$this->fatalError): ?>
<?= Form::open(['class' => 'layout']) ?>
<div class="layout-row">
<?= $this->formRender() ?>
</div>
<div class="form-buttons">
<div class="loading-indicator-container">
<button
type="submit"
data-request="onSave"
data-request-data="redirect:0"
data-hotkey="ctrl+s, cmd+s"
data-load-indicator="<?= e(trans('backend::lang.form.saving')) ?>"
class="btn btn-primary">
<?= e(trans('backend::lang.form.save')) ?>
</button>
<button
type="button"
data-request="onSave"
data-request-data="close:1"
data-hotkey="ctrl+enter, cmd+enter"
data-load-indicator="<?= e(trans('backend::lang.form.saving')) ?>"
class="btn btn-default">
<?= e(trans('backend::lang.form.save_and_close')) ?>
</button>
<button
type="button"
class="oc-icon-trash-o btn-icon danger pull-right"
data-request="onDelete"
data-load-indicator="<?= e(trans('backend::lang.form.deleting')) ?>"
data-request-confirm="<?= e(trans('backend::lang.form.confirm_delete')) ?>">
</button>
<span class="btn-text">
<?= e(trans('backend::lang.form.or')) ?> <a href="<?= Backend::url('akami/coffe30/partner') ?>"><?= e(trans('backend::lang.form.cancel')) ?></a>
</span>
</div>
</div>
<?= Form::close() ?>
<?php else: ?>
<p class="flash-message static error"><?= e(trans($this->fatalError)) ?></p>
<p><a href="<?= Backend::url('akami/coffe30/partner') ?>" class="btn btn-default"><?= e(trans('backend::lang.form.return_to_list')) ?></a></p>
<?php endif ?>

View File

@ -0,0 +1,18 @@
<div data-control="toolbar">
<a href="<?= Backend::url('akami/coffe30/stores/create') ?>" class="btn btn-primary oc-icon-plus"><?= e(trans('backend::lang.form.create')) ?></a>
<button
class="btn btn-default oc-icon-trash-o"
disabled="disabled"
onclick="$(this).data('request-data', {
checked: $('.control-list').listWidget('getChecked')
})"
data-request="onDelete"
data-request-confirm="<?= e(trans('backend::lang.list.delete_selected_confirm')) ?>"
data-trigger-action="enable"
data-trigger=".control-list input[type=checkbox]"
data-trigger-condition="checked"
data-request-success="$(this).prop('disabled', true)"
data-stripe-load-indicator>
<?= e(trans('backend::lang.list.delete_selected')) ?>
</button>
</div>

View File

@ -0,0 +1,10 @@
name: Stores
form: $/akami/coffe30/models/stores/fields.yaml
modelClass: Akami\Coffe30\Models\Stores
defaultRedirect: akami/coffe30/stores
create:
redirect: 'akami/coffe30/stores/update/:id'
redirectClose: akami/coffe30/stores
update:
redirect: akami/coffe30/stores
redirectClose: akami/coffe30/stores

View File

@ -0,0 +1,12 @@
list: $/akami/coffe30/models/stores/columns.yaml
modelClass: Akami\Coffe30\Models\Stores
title: Stores
noRecordsMessage: 'backend::lang.list.no_records'
showSetup: true
showCheckboxes: true
recordsPerPage: 20
toolbar:
buttons: list_toolbar
search:
prompt: 'backend::lang.list.search_prompt'
recordUrl: 'akami/coffe30/stores/update/:id'

View File

@ -0,0 +1,46 @@
<?php Block::put('breadcrumb') ?>
<ul>
<li><a href="<?= Backend::url('akami/coffe30/stores') ?>">Stores</a></li>
<li><?= e($this->pageTitle) ?></li>
</ul>
<?php Block::endPut() ?>
<?php if (!$this->fatalError): ?>
<?= Form::open(['class' => 'layout']) ?>
<div class="layout-row">
<?= $this->formRender() ?>
</div>
<div class="form-buttons">
<div class="loading-indicator-container">
<button
type="submit"
data-request="onSave"
data-hotkey="ctrl+s, cmd+s"
data-load-indicator="<?= e(trans('backend::lang.form.saving')) ?>"
class="btn btn-primary">
<?= e(trans('backend::lang.form.create')) ?>
</button>
<button
type="button"
data-request="onSave"
data-request-data="close:1"
data-hotkey="ctrl+enter, cmd+enter"
data-load-indicator="<?= e(trans('backend::lang.form.saving')) ?>"
class="btn btn-default">
<?= e(trans('backend::lang.form.create_and_close')) ?>
</button>
<span class="btn-text">
<?= e(trans('backend::lang.form.or')) ?> <a href="<?= Backend::url('akami/coffe30/stores') ?>"><?= e(trans('backend::lang.form.cancel')) ?></a>
</span>
</div>
</div>
<?= Form::close() ?>
<?php else: ?>
<p class="flash-message static error"><?= e(trans($this->fatalError)) ?></p>
<p><a href="<?= Backend::url('akami/coffe30/stores') ?>" class="btn btn-default"><?= e(trans('backend::lang.form.return_to_list')) ?></a></p>
<?php endif ?>

View File

@ -0,0 +1 @@
<?= $this->listRender() ?>

View File

@ -0,0 +1,22 @@
<?php Block::put('breadcrumb') ?>
<ul>
<li><a href="<?= Backend::url('akami/coffe30/stores') ?>">Stores</a></li>
<li><?= e($this->pageTitle) ?></li>
</ul>
<?php Block::endPut() ?>
<?php if (!$this->fatalError): ?>
<div class="form-preview">
<?= $this->formRenderPreview() ?>
</div>
<?php else: ?>
<p class="flash-message static error"><?= e($this->fatalError) ?></p>
<?php endif ?>
<p>
<a href="<?= Backend::url('akami/coffe30/stores') ?>" class="btn btn-default oc-icon-chevron-left">
<?= e(trans('backend::lang.form.return_to_list')) ?>
</a>
</p>

View File

@ -0,0 +1,54 @@
<?php Block::put('breadcrumb') ?>
<ul>
<li><a href="<?= Backend::url('akami/coffe30/stores') ?>">Stores</a></li>
<li><?= e($this->pageTitle) ?></li>
</ul>
<?php Block::endPut() ?>
<?php if (!$this->fatalError): ?>
<?= Form::open(['class' => 'layout']) ?>
<div class="layout-row">
<?= $this->formRender() ?>
</div>
<div class="form-buttons">
<div class="loading-indicator-container">
<button
type="submit"
data-request="onSave"
data-request-data="redirect:0"
data-hotkey="ctrl+s, cmd+s"
data-load-indicator="<?= e(trans('backend::lang.form.saving')) ?>"
class="btn btn-primary">
<?= e(trans('backend::lang.form.save')) ?>
</button>
<button
type="button"
data-request="onSave"
data-request-data="close:1"
data-hotkey="ctrl+enter, cmd+enter"
data-load-indicator="<?= e(trans('backend::lang.form.saving')) ?>"
class="btn btn-default">
<?= e(trans('backend::lang.form.save_and_close')) ?>
</button>
<button
type="button"
class="oc-icon-trash-o btn-icon danger pull-right"
data-request="onDelete"
data-load-indicator="<?= e(trans('backend::lang.form.deleting')) ?>"
data-request-confirm="<?= e(trans('backend::lang.form.confirm_delete')) ?>">
</button>
<span class="btn-text">
<?= e(trans('backend::lang.form.or')) ?> <a href="<?= Backend::url('akami/coffe30/stores') ?>"><?= e(trans('backend::lang.form.cancel')) ?></a>
</span>
</div>
</div>
<?= Form::close() ?>
<?php else: ?>
<p class="flash-message static error"><?= e(trans($this->fatalError)) ?></p>
<p><a href="<?= Backend::url('akami/coffe30/stores') ?>" class="btn btn-default"><?= e(trans('backend::lang.form.return_to_list')) ?></a></p>
<?php endif ?>

View File

@ -0,0 +1,23 @@
<?php namespace Akami\Coffe30\Models;
use Model;
/**
* Model
*/
class Comment extends Model
{
use \October\Rain\Database\Traits\Validation;
/**
* @var string The database table used by the model.
*/
public $table = 'akami_coffe30_comment';
/**
* @var array Validation rules
*/
public $rules = [
];
}

View File

@ -0,0 +1,23 @@
<?php namespace Akami\Coffe30\Models;
use Model;
/**
* Model
*/
class Partner extends Model
{
use \October\Rain\Database\Traits\Validation;
/**
* @var string The database table used by the model.
*/
public $table = 'akami_coffe30_partners';
/**
* @var array Validation rules
*/
public $rules = [
];
}

View File

@ -8,6 +8,7 @@ use Model;
class Slider extends Model
{
use \October\Rain\Database\Traits\Validation;
public $implement = ['@RainLab.Translate.Behaviors.TranslatableModel'];
/*
* Disable timestamps by default.
@ -21,6 +22,10 @@ class Slider extends Model
*/
public $table = 'akami_coffe30_slider';
public $translatable = [
'img',
];
/**
* @var array Validation rules
*/

View File

@ -0,0 +1,27 @@
<?php namespace Akami\Coffe30\Models;
use Model;
/**
* Model
*/
class Stores extends Model
{
use \October\Rain\Database\Traits\Validation;
public $implement = ['@RainLab.Translate.Behaviors.TranslatableModel'];
/**
* @var string The database table used by the model.
*/
public $table = 'akami_coffe30_stores';
public $translatable = [
'name',
];
/**
* @var array Validation rules
*/
public $rules = [
];
}

View File

@ -0,0 +1,13 @@
columns:
id:
label: id
type: number
header:
label: header
type: text
header2:
label: header2
type: text
txt:
label: txt
type: text

View File

@ -0,0 +1,13 @@
fields:
header:
label: Header
span: auto
type: text
header2:
label: Header2
span: auto
type: text
txt:
label: Txt
span: auto
type: textarea

View File

@ -0,0 +1,13 @@
columns:
id:
label: id
type: number
created_at:
label: created_at
type: datetime
note:
label: note
type: text
url:
label: url
type: text

View File

@ -0,0 +1,13 @@
fields:
img:
label: Img
span: auto
type: mediafinder
note:
label: Note
span: auto
type: text
url:
label: Url
span: auto
type: text

View File

@ -13,3 +13,9 @@ columns:
type: text
searchable: true
sortable: true
side:
label: side
type: text
txt1:
label: txt1
type: text

View File

@ -1,6 +1,7 @@
fields:
img:
label: Img
mode: file
span: auto
type: mediafinder
url:

View File

@ -0,0 +1,16 @@
columns:
id:
label: id
type: number
address:
label: address
type: text
created_at:
label: created_at
type: datetime
name:
label: name
type: text
updated_at:
label: updated_at
type: datetime

View File

@ -0,0 +1,13 @@
fields:
name:
label: Name
span: auto
type: text
address:
label: Address
span: auto
type: textarea
map:
label: Map
span: auto
type: textarea

View File

@ -14,3 +14,15 @@ navigation:
label: Slider
url: akami/coffe30/slider
icon: icon-image
side-menu-item2:
label: Comment
url: akami/coffe30/comment
icon: icon-comment
side-menu-item3:
label: Partners
url: akami/coffe30/partner
icon: icon-sitemap
side-menu-item4:
label: Magaziny
url: akami/coffe30/stores
icon: icon-building

View File

@ -0,0 +1,26 @@
<?php namespace Akami\Coffe30\Updates;
use Schema;
use October\Rain\Database\Updates\Migration;
class BuilderTableCreateAkamiCoffe30Comment extends Migration
{
public function up()
{
Schema::create('akami_coffe30_comment', function($table)
{
$table->engine = 'InnoDB';
$table->increments('id')->unsigned();
$table->timestamp('created_at')->nullable();
$table->timestamp('updated_at')->nullable();
$table->string('header')->nullable();
$table->string('header2')->nullable();
$table->text('txt');
});
}
public function down()
{
Schema::dropIfExists('akami_coffe30_comment');
}
}

View File

@ -0,0 +1,26 @@
<?php namespace Akami\Coffe30\Updates;
use Schema;
use October\Rain\Database\Updates\Migration;
class BuilderTableCreateAkamiCoffe30Partners extends Migration
{
public function up()
{
Schema::create('akami_coffe30_partners', function($table)
{
$table->engine = 'InnoDB';
$table->increments('id')->unsigned();
$table->timestamp('created_at')->nullable();
$table->timestamp('updated_at')->nullable();
$table->string('img')->nullable();
$table->string('url')->nullable();
$table->string('note')->nullable();
});
}
public function down()
{
Schema::dropIfExists('akami_coffe30_partners');
}
}

View File

@ -0,0 +1,26 @@
<?php namespace Akami\Coffe30\Updates;
use Schema;
use October\Rain\Database\Updates\Migration;
class BuilderTableCreateAkamiCoffe30Stored extends Migration
{
public function up()
{
Schema::create('akami_coffe30_stored', function($table)
{
$table->engine = 'InnoDB';
$table->increments('id')->unsigned();
$table->string('name');
$table->text('address')->nullable();
$table->text('map')->nullable();
$table->timestamp('created_at')->nullable();
$table->timestamp('updated_at')->nullable();
});
}
public function down()
{
Schema::dropIfExists('akami_coffe30_stored');
}
}

View File

@ -0,0 +1,25 @@
<?php namespace Akami\Coffe30\Updates;
use Schema;
use October\Rain\Database\Updates\Migration;
class BuilderTableUpdateAkamiCoffe30Comment extends Migration
{
public function up()
{
Schema::table('akami_coffe30_comment', function($table)
{
$table->string('header', 191)->nullable(false)->change();
$table->string('header2', 191)->nullable(false)->change();
});
}
public function down()
{
Schema::table('akami_coffe30_comment', function($table)
{
$table->string('header', 191)->nullable()->change();
$table->string('header2', 191)->nullable()->change();
});
}
}

View File

@ -0,0 +1,27 @@
<?php namespace Akami\Coffe30\Updates;
use Schema;
use October\Rain\Database\Updates\Migration;
class BuilderTableUpdateAkamiCoffe30Comment2 extends Migration
{
public function up()
{
Schema::table('akami_coffe30_comment', function($table)
{
$table->string('header', 191)->nullable()->change();
$table->string('header2', 191)->nullable()->change();
$table->text('txt')->nullable()->change();
});
}
public function down()
{
Schema::table('akami_coffe30_comment', function($table)
{
$table->string('header', 191)->nullable(false)->change();
$table->string('header2', 191)->nullable(false)->change();
$table->text('txt')->nullable(false)->change();
});
}
}

View File

@ -0,0 +1,31 @@
<?php namespace Akami\Coffe30\Updates;
use Schema;
use October\Rain\Database\Updates\Migration;
class BuilderTableUpdateAkamiCoffe30Slider extends Migration
{
public function up()
{
Schema::table('akami_coffe30_slider', function($table)
{
$table->string('side')->nullable();
$table->string('txt1')->nullable();
$table->string('txt2')->nullable();
$table->string('txt3')->nullable();
$table->string('btn_txt')->nullable();
});
}
public function down()
{
Schema::table('akami_coffe30_slider', function($table)
{
$table->dropColumn('side');
$table->dropColumn('txt1');
$table->dropColumn('txt2');
$table->dropColumn('txt3');
$table->dropColumn('btn_txt');
});
}
}

View File

@ -0,0 +1,23 @@
<?php namespace Akami\Coffe30\Updates;
use Schema;
use October\Rain\Database\Updates\Migration;
class BuilderTableUpdateAkamiCoffe30Slider2 extends Migration
{
public function up()
{
Schema::table('akami_coffe30_slider', function($table)
{
$table->string('side', 191)->default('left')->change();
});
}
public function down()
{
Schema::table('akami_coffe30_slider', function($table)
{
$table->string('side', 191)->default(null)->change();
});
}
}

View File

@ -0,0 +1,23 @@
<?php namespace Akami\Coffe30\Updates;
use Schema;
use October\Rain\Database\Updates\Migration;
class BuilderTableUpdateAkamiCoffe30Slider3 extends Migration
{
public function up()
{
Schema::table('akami_coffe30_slider', function($table)
{
$table->string('side', 191)->nullable(false)->change();
});
}
public function down()
{
Schema::table('akami_coffe30_slider', function($table)
{
$table->string('side', 191)->nullable()->change();
});
}
}

View File

@ -0,0 +1,23 @@
<?php namespace Akami\Coffe30\Updates;
use Schema;
use October\Rain\Database\Updates\Migration;
class BuilderTableUpdateAkamiCoffe30Slider4 extends Migration
{
public function up()
{
Schema::table('akami_coffe30_slider', function($table)
{
$table->string('side', 191)->nullable()->change();
});
}
public function down()
{
Schema::table('akami_coffe30_slider', function($table)
{
$table->string('side', 191)->nullable(false)->change();
});
}
}

View File

@ -0,0 +1,33 @@
<?php namespace Akami\Coffe30\Updates;
use Schema;
use October\Rain\Database\Updates\Migration;
class BuilderTableUpdateAkamiCoffe30Slider5 extends Migration
{
public function up()
{
Schema::table('akami_coffe30_slider', function($table)
{
$table->string('btn_txt', 191)->nullable(false)->change();
$table->string('side', 191)->nullable(false)->change();
$table->string('txt1', 191)->nullable(false)->change();
$table->string('txt2', 191)->nullable(false)->change();
$table->string('txt3', 191)->nullable(false)->change();
$table->string('url', 191)->nullable(false)->change();
});
}
public function down()
{
Schema::table('akami_coffe30_slider', function($table)
{
$table->string('btn_txt', 191)->nullable()->change();
$table->string('side', 191)->nullable()->change();
$table->string('txt1', 191)->nullable()->change();
$table->string('txt2', 191)->nullable()->change();
$table->string('txt3', 191)->nullable()->change();
$table->string('url', 191)->nullable()->change();
});
}
}

View File

@ -0,0 +1,33 @@
<?php namespace Akami\Coffe30\Updates;
use Schema;
use October\Rain\Database\Updates\Migration;
class BuilderTableUpdateAkamiCoffe30Slider6 extends Migration
{
public function up()
{
Schema::table('akami_coffe30_slider', function($table)
{
$table->string('btn_txt', 191)->nullable()->change();
$table->string('side', 191)->nullable()->change();
$table->string('txt1', 191)->nullable()->change();
$table->string('txt2', 191)->nullable()->change();
$table->string('txt3', 191)->nullable()->change();
$table->string('url', 191)->nullable()->change();
});
}
public function down()
{
Schema::table('akami_coffe30_slider', function($table)
{
$table->string('btn_txt', 191)->nullable(false)->change();
$table->string('side', 191)->nullable(false)->change();
$table->string('txt1', 191)->nullable(false)->change();
$table->string('txt2', 191)->nullable(false)->change();
$table->string('txt3', 191)->nullable(false)->change();
$table->string('url', 191)->nullable(false)->change();
});
}
}

View File

@ -0,0 +1,23 @@
<?php namespace Akami\Coffe30\Updates;
use Schema;
use October\Rain\Database\Updates\Migration;
class BuilderTableUpdateAkamiCoffe30Slider7 extends Migration
{
public function up()
{
Schema::table('akami_coffe30_slider', function($table)
{
$table->string('img', 191)->nullable()->change();
});
}
public function down()
{
Schema::table('akami_coffe30_slider', function($table)
{
$table->string('img', 191)->nullable(false)->change();
});
}
}

View File

@ -0,0 +1,23 @@
<?php namespace Akami\Coffe30\Updates;
use Schema;
use October\Rain\Database\Updates\Migration;
class BuilderTableUpdateAkamiCoffe30Slider8 extends Migration
{
public function up()
{
Schema::table('akami_coffe30_slider', function($table)
{
$table->string('img', 191)->nullable(false)->change();
});
}
public function down()
{
Schema::table('akami_coffe30_slider', function($table)
{
$table->string('img', 191)->nullable()->change();
});
}
}

View File

@ -0,0 +1,17 @@
<?php namespace Akami\Coffe30\Updates;
use Schema;
use October\Rain\Database\Updates\Migration;
class BuilderTableUpdateAkamiCoffe30Stores extends Migration
{
public function up()
{
Schema::rename('akami_coffe30_stored', 'akami_coffe30_stores');
}
public function down()
{
Schema::rename('akami_coffe30_stores', 'akami_coffe30_stored');
}
}

View File

@ -3,3 +3,45 @@
1.0.2:
- 'Created table akami_coffe30_slider'
- builder_table_create_akami_coffe30_slider.php
1.0.3:
- 'Updated table akami_coffe30_slider'
- builder_table_update_akami_coffe30_slider.php
1.0.4:
- 'Updated table akami_coffe30_slider'
- builder_table_update_akami_coffe30_slider_2.php
1.0.5:
- 'Created table akami_coffe30_comment'
- builder_table_create_akami_coffe30_comment.php
1.0.6:
- 'Created table akami_coffe30_partners'
- builder_table_create_akami_coffe30_partners.php
1.0.7:
- 'Updated table akami_coffe30_slider'
- builder_table_update_akami_coffe30_slider_3.php
1.0.8:
- 'Updated table akami_coffe30_slider'
- builder_table_update_akami_coffe30_slider_4.php
1.0.9:
- 'Updated table akami_coffe30_slider'
- builder_table_update_akami_coffe30_slider_5.php
1.0.10:
- 'Updated table akami_coffe30_slider'
- builder_table_update_akami_coffe30_slider_6.php
1.0.11:
- 'Updated table akami_coffe30_comment'
- builder_table_update_akami_coffe30_comment.php
1.0.12:
- 'Updated table akami_coffe30_comment'
- builder_table_update_akami_coffe30_comment_2.php
1.0.13:
- 'Updated table akami_coffe30_slider'
- builder_table_update_akami_coffe30_slider_7.php
1.0.14:
- 'Updated table akami_coffe30_slider'
- builder_table_update_akami_coffe30_slider_8.php
1.0.15:
- 'Created table akami_coffe30_stored'
- builder_table_create_akami_coffe30_stored.php
1.0.16:
- 'Updated table akami_coffe30_stored'
- builder_table_update_akami_coffe30_stores.php

View File

@ -0,0 +1,23 @@
<?php namespace Lovata\Buddies\Updates;
use Schema;
use October\Rain\Database\Updates\Migration;
class BuilderTableUpdateLovataBuddiesUsers extends Migration
{
public function up()
{
Schema::table('lovata_buddies_users', function($table)
{
$table->increments('id')->change();
});
}
public function down()
{
Schema::table('lovata_buddies_users', function($table)
{
$table->integer('id')->change();
});
}
}

View File

@ -7,7 +7,7 @@
1.0.1:
- '$casts property is replaced with $jsonable property in the User model'
1.1.0:
- "Added the ability to edit the user's properties using the UserPage component on different pages and forms. For example, for pages: personal data, company legal data, etc."
- 'Added the ability to edit the user''s properties using the UserPage component on different pages and forms. For example, for pages: personal data, company legal data, etc.'
1.2.0:
- 'Added onCheckEmail() method in Registration component. Added the ability to add custom fields to email templates. Added events: "lovata.buddies::mail.registration.template.data", "lovata.buddies::mail.restore.template.data". Added support for multilanguage for sending emails. Settings for sending emails are moved to the Toolbox plugin. Requires Toolbox plugin version 1.6.0 and later.'
1.3.0:
@ -37,3 +37,6 @@
- 'Added composer.json to plugin'
1.9.1:
- 'Updated composer.json file'
1.9.2:
- 'Updated table lovata_buddies_users'
- builder_table_update_lovata_buddies_users.php

View File

@ -15,7 +15,7 @@ columns:
searchable: true
sortable: true
id:
label: 'lovata.toolbox::lang.field.id'
label: ID
type: text
searchable: true
sortable: true
@ -26,7 +26,7 @@ columns:
searchable: true
sortable: true
external_id:
label: 'lovata.toolbox::lang.field.external_id'
label: EXTERNAL
type: text
searchable: true
sortable: true

View File

@ -53,3 +53,11 @@ columns:
type: timetense
sortable: true
invisible: true
category_id:
label: CAT_ID
type: text
searchable: true
sortable: true
featured:
label: featured
type: text

View File

@ -0,0 +1,23 @@
<?php namespace Lovata\Shopaholic\Updates;
use Schema;
use October\Rain\Database\Updates\Migration;
class BuilderTableUpdateLovataShopaholicMeasure extends Migration
{
public function up()
{
Schema::table('lovata_shopaholic_measure', function($table)
{
$table->increments('id')->change();
});
}
public function down()
{
Schema::table('lovata_shopaholic_measure', function($table)
{
$table->integer('id')->change();
});
}
}

View File

@ -0,0 +1,23 @@
<?php namespace Lovata\Shopaholic\Updates;
use Schema;
use October\Rain\Database\Updates\Migration;
class BuilderTableUpdateLovataShopaholicPrices extends Migration
{
public function up()
{
Schema::table('lovata_shopaholic_prices', function($table)
{
$table->increments('id')->change();
});
}
public function down()
{
Schema::table('lovata_shopaholic_prices', function($table)
{
$table->integer('id')->change();
});
}
}

View File

@ -0,0 +1,23 @@
<?php namespace Lovata\Shopaholic\Updates;
use Schema;
use October\Rain\Database\Updates\Migration;
class BuilderTableUpdateLovataShopaholicProducts extends Migration
{
public function up()
{
Schema::table('lovata_shopaholic_products', function($table)
{
$table->increments('id')->change();
});
}
public function down()
{
Schema::table('lovata_shopaholic_products', function($table)
{
$table->integer('id')->change();
});
}
}

View File

@ -139,3 +139,12 @@
1.30.3:
- 'Updated table lovata_shopaholic_categories'
- builder_table_update_lovata_shopaholic_categories.php
1.30.4:
- 'Updated table lovata_shopaholic_products'
- builder_table_update_lovata_shopaholic_products.php
1.30.5:
- 'Updated table lovata_shopaholic_measure'
- builder_table_update_lovata_shopaholic_measure.php
1.30.6:
- 'Updated table lovata_shopaholic_prices'
- builder_table_update_lovata_shopaholic_prices.php

BIN
plugins/toughdeveloper/.DS_Store vendored Normal file

Binary file not shown.

Binary file not shown.

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;
}
}

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