Prepare for CDN, config rename cms.plugins|themes|uploadsDir -> cms.plugins|themes|uploadsPath

Deprecate data-trigger-type on triggerapi
Fixes ref to Util class
This commit is contained in:
Samuel Georges 2015-02-17 20:58:38 +11:00
parent 7b52e07b65
commit 7145aac457
25 changed files with 99 additions and 153 deletions

View File

@ -154,36 +154,39 @@ return array(
/*
|--------------------------------------------------------------------------
| Plugins directory
| Public plugins path
|--------------------------------------------------------------------------
|
| Specifies the plugins directory relative to the application root directory.
| Specifies the public plugins path relative to the application base URL,
| or you can specify a full URL path.
|
*/
'pluginsDir' => '/plugins',
'pluginsPath' => '/plugins',
/*
|--------------------------------------------------------------------------
| Themes directory
| Public themes path
|--------------------------------------------------------------------------
|
| Specifies the themes directory relative to the application root directory.
| Specifies the public themes path relative to the application base URL,
| or you can specify a full URL path.
|
*/
'themesDir' => '/themes',
'themesPath' => '/themes',
/*
|--------------------------------------------------------------------------
| Uploads directory
| Public uploads path
|--------------------------------------------------------------------------
|
| Specifies the uploads directory relative to the application root directory.
| Specifies the public uploads path relative to the application base URL,
| or you can specify a full URL path.
|
*/
'uploadsDir' => '/uploads',
'uploadsPath' => '/uploads',
/*
|--------------------------------------------------------------------------

View File

@ -1,6 +1,6 @@
<?php
return array(
return [
/*
|--------------------------------------------------------------------------
@ -13,28 +13,6 @@ return array(
'activeTheme' => 'test',
/*
|--------------------------------------------------------------------------
| Plugins directory
|--------------------------------------------------------------------------
|
| Specifies the plugins directory relative to the application root directory.
|
*/
'pluginsDir' => '/tests/fixtures/plugins',
/*
|--------------------------------------------------------------------------
| Themes directory
|--------------------------------------------------------------------------
|
| Specifies the themes directory relative to the application root directory.
|
*/
'themesDir' => '/tests/fixtures/themes',
/*
|--------------------------------------------------------------------------
| Time to live for parsed CMS objects.
@ -109,19 +87,4 @@ return array(
'convertLineEndings' => true,
/*
|--------------------------------------------------------------------------
| Linking policy
|--------------------------------------------------------------------------
|
| Controls how URL links are generated throughout the application.
|
| detect - detect hostname and use the current schema
| secure - detect hostname and force HTTPS schema
| insecure - detect hostname and force HTTP schema
| force - force hostname and schema using app.url config value
|
*/
'linkPolicy' => 'detect',
);
];

View File

@ -67,12 +67,13 @@ if($.oc===undefined)
$.oc={}
$.oc.escapeHtmlString=function(string){var htmlEscapes={'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#x27;','/':'&#x2F;'},htmlEscaper=/[&<>"'\/]/g
return(''+string).replace(htmlEscaper,function(match){return htmlEscapes[match];})}
+function($){"use strict";var TriggerOn=function(element,options){var $el=this.$el=$(element);this.options=options||{};if(this.options.triggerCondition===false)
+function($){"use strict";var TriggerOn=function(element,options){var $el=this.$el=$(element);this.options=options||{};if(this.options.triggerType!==false&&this.options.triggerAction===false)this.options.triggerAction=this.options.triggerType
if(this.options.triggerCondition===false)
throw new Error('Trigger condition is not specified.')
if(this.options.trigger===false)
throw new Error('Trigger selector is not specified.')
if(this.options.triggerType===false)
throw new Error('Trigger type is not specified.')
if(this.options.triggerAction===false)
throw new Error('Trigger action is not specified.')
this.triggerCondition=this.options.triggerCondition
if(this.options.triggerCondition.indexOf('value')==0){var match=this.options.triggerCondition.match(/[^[\]]+(?=])/g)
if(match){this.triggerConditionValue=match
@ -85,23 +86,23 @@ self.onConditionChanged()})
self.onConditionChanged()}
TriggerOn.prototype.onConditionChanged=function(){if(this.triggerCondition=='checked'){this.updateTarget($(this.options.trigger+':checked').length>0)}
else if(this.triggerCondition=='value'){this.updateTarget($(this.options.trigger).val()==this.triggerConditionValue)}}
TriggerOn.prototype.updateTarget=function(status){if(this.options.triggerType=='show')
TriggerOn.prototype.updateTarget=function(status){if(this.options.triggerAction=='show')
this.$el.toggleClass('hide',!status).trigger('hide',[!status])
else if(this.options.triggerType=='hide')
else if(this.options.triggerAction=='hide')
this.$el.toggleClass('hide',status).trigger('hide',[status])
else if(this.options.triggerType=='enable')
else if(this.options.triggerAction=='enable')
this.$el.prop('disabled',!status).trigger('disable',[!status]).toggleClass('control-disabled',!status)
else if(this.options.triggerType=='disable')
else if(this.options.triggerAction=='disable')
this.$el.prop('disabled',status).trigger('disable',[status]).toggleClass('control-disabled',status)
else if(this.options.triggerType=='empty'&&status)
else if(this.options.triggerAction=='empty'&&status)
this.$el.trigger('empty').val('')
if(this.options.triggerType=='show'||this.options.triggerType=='hide')
if(this.options.triggerAction=='show'||this.options.triggerAction=='hide')
this.fixButtonClasses()
$(window).trigger('resize')}
TriggerOn.prototype.fixButtonClasses=function(){var group=this.$el.closest('.btn-group')
if(group.length>0&&this.$el.is(':last-child'))
this.$el.prev().toggleClass('last',this.$el.hasClass('hide'))}
TriggerOn.DEFAULTS={triggerCondition:false,trigger:false,triggerType:false}
TriggerOn.DEFAULTS={triggerAction:false,triggerCondition:false,trigger:false}
var old=$.fn.triggerOn
$.fn.triggerOn=function(option){return this.each(function(){var $this=$(this)
var data=$this.data('oc.triggerOn')

View File

@ -6,7 +6,7 @@
* element is checked.
*
* Supported data attributes:
* - data-trigger-type, values: show, hide, enable, disable, empty
* - data-trigger-action, values: show, hide, enable, disable, empty
* - data-trigger: a CSS selector for elements that trigger the action (checkboxes)
* - data-trigger-condition, values:
* - checked: determines the condition the elements specified in the data-trigger
@ -15,7 +15,7 @@
* the condition is considered "true".
*
* Example: <input type="button" class="btn disabled"
* data-trigger-type="enable"
* data-trigger-action="enable"
* data-trigger="#cblist input[type=checkbox]"
* data-trigger-condition="checked" ... >
*
@ -24,7 +24,7 @@
* force it to check the condition and update itself. This is useful when the page content is updated with AJAX.
*
* JavaScript API:
* $('#mybutton').triggerOn({triggerCondition: 'checked', trigger: '#cblist input[type=checkbox]', triggerType: 'enable'})
* $('#mybutton').triggerOn({ triggerCondition: 'checked', trigger: '#cblist input[type=checkbox]', triggerAction: 'enable' })
*/
+function ($) { "use strict";
@ -34,14 +34,17 @@
this.options = options || {};
// @deprecated remove if year >= 2016
if (this.options.triggerType !== false && this.options.triggerAction === false) this.options.triggerAction = this.options.triggerType
if (this.options.triggerCondition === false)
throw new Error('Trigger condition is not specified.')
if (this.options.trigger === false)
throw new Error('Trigger selector is not specified.')
if (this.options.triggerType === false)
throw new Error('Trigger type is not specified.')
if (this.options.triggerAction === false)
throw new Error('Trigger action is not specified.')
this.triggerCondition = this.options.triggerCondition
@ -75,18 +78,18 @@
}
TriggerOn.prototype.updateTarget = function(status) {
if (this.options.triggerType == 'show')
if (this.options.triggerAction == 'show')
this.$el.toggleClass('hide', !status).trigger('hide', [!status])
else if (this.options.triggerType == 'hide')
else if (this.options.triggerAction == 'hide')
this.$el.toggleClass('hide', status).trigger('hide', [status])
else if (this.options.triggerType == 'enable')
else if (this.options.triggerAction == 'enable')
this.$el.prop('disabled', !status).trigger('disable', [!status]).toggleClass('control-disabled', !status)
else if (this.options.triggerType == 'disable')
else if (this.options.triggerAction == 'disable')
this.$el.prop('disabled', status).trigger('disable', [status]).toggleClass('control-disabled', status)
else if (this.options.triggerType == 'empty' && status)
else if (this.options.triggerAction == 'empty' && status)
this.$el.trigger('empty').val('')
if (this.options.triggerType == 'show' || this.options.triggerType == 'hide')
if (this.options.triggerAction == 'show' || this.options.triggerAction == 'hide')
this.fixButtonClasses()
$(window).trigger('resize')
@ -100,9 +103,9 @@
}
TriggerOn.DEFAULTS = {
triggerAction: false,
triggerCondition: false,
trigger: false,
triggerType: false
trigger: false
}
// TRIGGERON PLUGIN DEFINITION

View File

@ -9,7 +9,6 @@ use Redirect;
use Backend;
use Backend\Classes\FormField;
use Backend\Classes\ControllerBehavior;
use October\Rain\Support\Util;
use October\Rain\Router\Helper as RouterHelper;
use ApplicationException;
use Exception;

View File

@ -15,7 +15,7 @@
disabled="disabled"
data-request="onRelationButtonDelete"
data-request-confirm="<?= e(trans('backend::lang.relation.delete_confirm')) ?>"
data-trigger-type="enable"
data-trigger-action="enable"
data-trigger="#<?= $this->relationGetId('view') ?> .control-list input[type=checkbox]"
data-trigger-condition="checked"
data-stripe-load-indicator>

View File

@ -13,7 +13,7 @@
})"
disabled="disabled"
data-request="onRelationButtonRemove"
data-trigger-type="enable"
data-trigger-action="enable"
data-trigger="#<?= $this->relationGetId('view') ?> .control-list input[type=checkbox]"
data-trigger-condition="checked"
data-stripe-load-indicator>

View File

@ -42,16 +42,6 @@ class ControllerBehavior extends ExtensionBase
public function __construct($controller)
{
$this->controller = $controller;
// Option A: (@todo Determine which is faster by benchmark)
// $relativePath = strtolower(str_replace('\\', '/', get_called_class()));
// $this->viewPath = $this->configPath = [
// 'modules/' . $relativePath . '/partials',
// 'plugins/' . $relativePath . '/partials'
// ];
// $this->assetPath = ['modules/' . $relativePath . '/assets', 'plugins/' . $relativePath . '/assets'];
// Option B:
$this->viewPath = $this->configPath = $this->guessViewPath('/partials');
$this->assetPath = $this->guessViewPath('/assets', true);

View File

@ -48,16 +48,6 @@ abstract class WidgetBase
public function __construct($controller, $configuration = [])
{
$this->controller = $controller;
// Option A: (@todo Determine which is faster by benchmark)
// $relativePath = strtolower(str_replace('\\', '/', get_called_class()));
// $this->viewPath = $this->configPath = [
// 'modules/' . $relativePath . '/partials',
// 'plugins/' . $relativePath . '/partials'
// ];
// $this->assetPath = ['modules/' . $relativePath . '/assets', 'plugins/' . $relativePath . '/assets'];
// Option B:
$this->viewPath = $this->configPath = $this->guessViewPath('/partials');
$this->assetPath = $this->guessViewPath('/assets', true);

View File

@ -108,8 +108,8 @@ class Users extends Controller
-1 => 'backend::lang.user.deny',
],
'attributes' => [
'data-trigger-action' => 'disable',
'data-trigger' => "input[name='User[permissions][superuser]']",
'data-trigger-type' => 'disable',
'data-trigger-condition' => 'checked',
],
'span' => 'auto',

View File

@ -6,13 +6,13 @@
<button
class="btn btn-default oc-icon-ban-circle"
disabled="disabled"
data-trigger-type="enable"
data-trigger-action="enable"
data-trigger=".control-list input[type=checkbox]"
data-trigger-condition="checked">Ban</button>
<button
class="btn btn-default oc-icon-trash-o"
disabled="disabled"
data-trigger-type="enable"
data-trigger-action="enable"
data-trigger=".control-list input[type=checkbox]"
data-trigger-condition="checked">Delete</button>
</div>

View File

@ -5,7 +5,6 @@ use Event;
use Backend\Classes\WidgetBase;
use Backend\Classes\FilterScope;
use ApplicationException;
use October\Rain\Support\Util;
/**
* Filter Widget
@ -126,7 +125,7 @@ class Filter extends WidgetBase
$params = func_get_args();
$result = $this->fireEvent('filter.update', [$params]);
if ($result && is_array($result)) {
return Util::arrayMerge($result);
return call_user_func_array('array_merge', $result);
}
}

View File

@ -245,6 +245,7 @@ class Form extends WidgetBase
protected function prepareVars()
{
$this->defineFormFields();
$this->applyFiltersFromModel();
$this->vars['sessionKey'] = $this->getSessionKey();
$this->vars['outsideTabs'] = $this->outsideTabs;
$this->vars['primaryTabs'] = $this->primaryTabs;
@ -840,6 +841,16 @@ class Form extends WidgetBase
return $data;
}
/*
* Allow the model to filter fields.
*/
protected function applyFiltersFromModel()
{
if (method_exists($this->model, 'filterFields')) {
$this->model->filterFields((object) $this->fields);
}
}
/**
* Looks at the model for defined options.
*/

View File

@ -1,7 +1,6 @@
<?php namespace Backend\Widgets;
use Input;
use October\Rain\Support\Util;
use Backend\Classes\WidgetBase;
/**
@ -116,7 +115,7 @@ class Search extends WidgetBase
$params = func_get_args();
$result = $this->fireEvent('search.submit', [$params]);
if ($result && is_array($result)) {
return Util::arrayMerge($result);
return call_user_func_array('array_merge', $result);
}
}

View File

@ -93,7 +93,7 @@ abstract class ComponentBase extends Extendable
$className = Str::normalizeClassName(get_called_class());
$this->dirName = strtolower(str_replace('\\', '/', $className));
$this->assetPath = Config::get('cms.pluginsDir').dirname(dirname($this->dirName));
$this->assetPath = Config::get('cms.pluginsPath', '/plugins').dirname(dirname($this->dirName));
parent::__construct();
}

View File

@ -122,7 +122,7 @@ class Controller
throw new CmsException(Lang::get('cms::lang.theme.active.not_found'));
}
$this->assetPath = Config::get('cms.themesDir').'/'.$this->theme->getDirName();
$this->assetPath = Config::get('cms.themesPath', '/themes').'/'.$this->theme->getDirName();
$this->router = new Router($this->theme);
$this->initTwigEnvironment();
@ -1042,13 +1042,13 @@ class Controller
*/
public function themeUrl($url = null)
{
$themePath = Config::get('cms.themesDir').'/'.$this->getTheme()->getDirName();
$themeDir = $this->getTheme()->getDirName();
if (is_array($url)) {
$_url = URL::to(CombineAssets::combine($url, $themePath));
$_url = URL::to(CombineAssets::combine($url, themes_path().'/'.$themeDir));
}
else {
$_url = $themePath;
$_url = Config::get('cms.themesPath', '/themes').'/'.$themeDir;
if ($url !== null) {
$_url .= '/'.$url;
}

View File

@ -68,7 +68,7 @@ class Theme
$dirName = $this->getDirName();
}
return base_path().Config::get('cms.themesDir').'/'.$dirName;
return themes_path().'/'.$dirName;
}
/**
@ -211,9 +211,7 @@ class Theme
*/
public static function all()
{
$path = base_path().Config::get('cms.themesDir');
$it = new DirectoryIterator($path);
$it = new DirectoryIterator(themes_path());
$it->rewind();
$result = [];

View File

@ -26,7 +26,7 @@
<div class="dropdown hide"
id="<?= $this->getId('tools-button') ?>"
data-trigger-type="show"
data-trigger-action="show"
data-trigger="<?= '#'.$this->getId('asset-list') ?> input[type=checkbox]"
data-trigger-condition="checked">
<button type="button" class="btn btn-primary empty oc-icon-wrench last"

View File

@ -10,7 +10,7 @@
id="<?= $this->getId('delete-button') ?>"
data-control="delete-template"
data-confirmation="<?= e(trans($this->deleteConfirmation)) ?>"
data-trigger-type="show"
data-trigger-action="show"
data-trigger="<?= '#'.$this->getId('template-list') ?> input[type=checkbox]"
data-trigger-condition="checked"></button>
</div>

View File

@ -54,9 +54,9 @@ class CombineAssets
protected $filters = [];
/**
* @var string The directory path context to find assets.
* @var string The local path context to find assets.
*/
protected $path;
protected $localPath;
/**
* @var string The output folder for storing combined files.
@ -134,9 +134,9 @@ class CombineAssets
* to produce a page relative URL to the combined contents.
* @return string URL to contents.
*/
public static function combine($assets = [], $prefixPath = null)
public static function combine($assets = [], $localPath = null)
{
return self::instance()->prepareRequest($assets, $prefixPath);
return self::instance()->prepareRequest($assets, $localPath);
}
/**
@ -170,7 +170,7 @@ class CombineAssets
throw new ApplicationException(Lang::get('cms::lang.combiner.not_found', ['name'=>$cacheId]));
}
$this->path = $cacheInfo['path'];
$this->localPath = $cacheInfo['path'];
$this->storagePath = storage_path().'/cms/combiner/assets';
$combiner = $this->prepareCombiner($cacheInfo['files']);
@ -271,13 +271,13 @@ class CombineAssets
* @var string File extension, used for aesthetic purposes only.
* @return string URL to contents.
*/
protected function prepareRequest(array $assets, $path = null)
protected function prepareRequest(array $assets, $localPath = null)
{
if (substr($path, -1) != '/') {
$path = $path.'/';
if (substr($localPath, -1) != '/') {
$localPath = $localPath.'/';
}
$this->path = public_path().$path;
$this->localPath = $localPath;
$this->storagePath = storage_path().'/cms/combiner/assets';
list($assets, $extension) = $this->prepareAssets($assets);
@ -297,7 +297,7 @@ class CombineAssets
'etag' => $cacheId,
'lastMod' => $lastMod,
'files' => $assets,
'path' => $this->path,
'path' => $this->localPath,
'extension' => $extension
];
@ -317,9 +317,9 @@ class CombineAssets
$filesSalt = null;
foreach ($assets as $asset) {
$filters = $this->getFilters(File::extension($asset)) ?: [];
$path = File::symbolizePath($asset) ?: $this->path . $asset;
$path = File::symbolizePath($asset) ?: $this->localPath . $asset;
$files[] = new FileAsset($path, $filters, public_path());
$filesSalt .= $this->path . $asset;
$filesSalt .= $this->localPath . $asset;
}
$filesSalt = md5($filesSalt);
@ -638,7 +638,7 @@ class CombineAssets
*/
protected function makeCacheId(array $assets)
{
return md5($this->path . implode('|', $assets));
return md5($this->localPath . implode('|', $assets));
}
/**

View File

@ -120,15 +120,10 @@ class OctoberUtil extends Command
protected function utilPurgeThumbs()
{
if (!$uploadsDir = Config::get('cms.uploadsDir')) {
return $this->error('No uploads directory defined in config (cms.uploadsDir)');
}
if (!$this->confirmToProceed('This will PERMANENTLY DELETE all thumbs in the uploads directory.')) {
return;
}
$uploadsDir = base_path() . $uploadsDir;
$totalCount = 0;
/*
@ -151,7 +146,7 @@ class OctoberUtil extends Command
}
};
$purgeFunc($uploadsDir);
$purgeFunc(uploads_path());
if ($totalCount > 0) {
$this->comment(sprintf('Successfully deleted %s thumbs', $totalCount));

View File

@ -8,7 +8,7 @@
})"
data-control="popup"
data-handler="onLoadDisableForm"
data-trigger-type="enable"
data-trigger-action="enable"
data-trigger=".control-list input[type=checkbox]"
data-trigger-condition="checked"
data-stripe-load-indicator>
@ -23,7 +23,7 @@
})"
data-request="onRefreshPlugins"
data-request-confirm="<?= e(trans('system::lang.plugins.refresh_confirm')) ?>"
data-trigger-type="enable"
data-trigger-action="enable"
data-trigger=".control-list input[type=checkbox]"
data-trigger-condition="checked"
data-stripe-load-indicator>
@ -38,7 +38,7 @@
})"
data-request="onRemovePlugins"
data-request-confirm="<?= e(trans('system::lang.plugins.remove_confirm')) ?>"
data-trigger-type="enable"
data-trigger-action="enable"
data-trigger=".control-list input[type=checkbox]"
data-trigger-condition="checked"
data-stripe-load-indicator>

View File

@ -26,12 +26,11 @@ class File extends FileBase
*/
public function getStorageDirectory()
{
$uploadsDir = Config::get('cms.uploadsDir');
if ($this->isPublic()) {
return base_path() . $uploadsDir . '/public/';
return uploads_path() . '/public/';
}
else {
return base_path() . $uploadsDir . '/protected/';
return uploads_path() . '/protected/';
}
}
@ -40,12 +39,17 @@ class File extends FileBase
*/
public function getPublicDirectory()
{
$uploadsDir = Config::get('cms.uploadsDir');
$uploadsPath = Config::get('cms.uploadsPath', '/uploads');
if (!preg_match("/(\/\/|http|https)/", $uploadsPath)) {
$uploadsPath = Request::getBasePath() . $uploadsPath;
}
if ($this->isPublic()) {
return Request::getBasePath() . $uploadsDir . '/public/';
return $uploadsPath . '/public/';
}
else {
return Request::getBasePath() . $uploadsDir . '/protected/';
return $uploadsPath . '/protected/';
}
}
}

View File

@ -195,7 +195,7 @@ trait AssetMaker
* a forward slash, it will be returned in context of the application public path,
* otherwise it will be returned in context of the asset path.
* @param string $fileName File to load.
* @param mixed $assetPath Explicitly define an asset path.
* @param string $assetPath Explicitly define an asset path.
* @return string Relative path to the asset file.
*/
public function getAssetPath($fileName, $assetPath = null)
@ -212,18 +212,7 @@ trait AssetMaker
return $fileName;
}
if (!is_array($assetPath)) {
$assetPath = [$assetPath];
}
foreach ($assetPath as $path) {
$_fileName = $path . '/' . $fileName;
if (File::isFile(base_path() . '/' . $_fileName)) {
break;
}
}
return $_fileName;
return $assetPath . '/' . $fileName;
}
/**

View File

@ -16,6 +16,8 @@ class TestCase extends Illuminate\Foundation\Testing\TestCase
$app['cache']->setDefaultDriver('array');
$app->setLocale('en');
$app->setPluginsPath(base_path().'/tests/fixtures/plugins');
$app->setThemesPath(base_path().'/tests/fixtures/themes');
return $app;
}