Merge branch 'develop' into stable
This commit is contained in:
commit
4ddc8055c6
|
|
@ -1,8 +1,8 @@
|
|||
* **Build 317** (2015-02-24)
|
||||
* **Build 317** (2016-02-24)
|
||||
- The `/404` route now returns 404 HTTP response code as it should.
|
||||
- Updated the `.htaccess` file with a minor security precaution.
|
||||
|
||||
* **Build 316** (2015-02-11)
|
||||
* **Build 316** (2016-02-11)
|
||||
- Various back-end UI enhancements used for the [Builder plugin](http://octobercms.com/plugin/rainlab-builder).
|
||||
|
||||
* **Build 313** (2015-12-12)
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ class CmsController extends ControllerBase
|
|||
|
||||
/**
|
||||
* Extend this object properties upon construction.
|
||||
* @param Closure $callback
|
||||
*/
|
||||
public static function extend(Closure $callback)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ class CmsObject implements ArrayAccess
|
|||
/**
|
||||
* Loads the object from a cache.
|
||||
* This method is used by the CMS in the runtime. If the cache is not found, it is created.
|
||||
* @param $theme Specifies the theme the object belongs to.
|
||||
* @param \Cms\Classes\Theme $theme Specifies the theme the object belongs to.
|
||||
* @param string $fileName Specifies the file name, with the extension.
|
||||
* @return mixed Returns a CMS object instance or null if the object wasn't found.
|
||||
*/
|
||||
|
|
@ -149,7 +149,7 @@ class CmsObject implements ArrayAccess
|
|||
/**
|
||||
* Loads the object from a file.
|
||||
* This method is used in the CMS back-end. It doesn't use any caching.
|
||||
* @param $theme Specifies the theme the object belongs to.
|
||||
* @param \Cms\Classes\Theme $theme Specifies the theme the object belongs to.
|
||||
* @param string $fileName Specifies the file name, with the extension.
|
||||
* The file name can contain only alphanumeric symbols, dashes and dots.
|
||||
* @return mixed Returns a CMS object instance or null if the object wasn't found.
|
||||
|
|
@ -446,7 +446,7 @@ class CmsObject implements ArrayAccess
|
|||
|
||||
/**
|
||||
* Returns the absolute file path.
|
||||
* @param $theme Specifies a theme the file belongs to.
|
||||
* @param \Cms\Classes\Theme $theme Specifies a theme the file belongs to.
|
||||
* @param string$fileName Specifies the file name to return the path to.
|
||||
* @return string
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -13,7 +13,8 @@ class CmsObjectCollection extends CollectionBase
|
|||
{
|
||||
/**
|
||||
* Returns objects that use the supplied component.
|
||||
* @param string|array $components
|
||||
* @param string|array $components
|
||||
* @param null|callback $callback
|
||||
* @return static
|
||||
*/
|
||||
public function withComponent($components, $callback = null)
|
||||
|
|
@ -41,6 +42,7 @@ class CmsObjectCollection extends CollectionBase
|
|||
* Returns objects whose properties match the supplied value.
|
||||
* @param string $property
|
||||
* @param string $value
|
||||
* @param bool $strict
|
||||
* @return static
|
||||
*/
|
||||
public function where($property, $value, $strict = true)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
<?php namespace Cms\Classes;
|
||||
|
||||
use Str;
|
||||
use Illuminate\Container\Container;
|
||||
use System\Classes\PluginManager;
|
||||
use SystemException;
|
||||
use Illuminate\Support\Facades\App;
|
||||
|
|
@ -81,6 +80,7 @@ class ComponentManager
|
|||
* });
|
||||
* </pre>
|
||||
*
|
||||
* @param callable $definitions
|
||||
* @return array Array values are class names.
|
||||
*/
|
||||
public function registerComponents(callable $definitions)
|
||||
|
|
@ -189,7 +189,7 @@ class ComponentManager
|
|||
|
||||
/**
|
||||
* Makes a component object with properties set.
|
||||
* @param $name A component class name or code.
|
||||
* @param string $name A component class name or code.
|
||||
* @param CmsObject $cmsObject The Cms object that spawned this component.
|
||||
* @param array $properties The properties set by the Page or Layout.
|
||||
* @return ComponentBase The component object.
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ class Layout extends CmsCompoundObject
|
|||
|
||||
/**
|
||||
* Initializes the fallback layout.
|
||||
* @param \Cms\ClassesTheme $theme Specifies a theme the file belongs to.
|
||||
* @param \Cms\Classes\Theme $theme Specifies a theme the file belongs to.
|
||||
* @return \Cms\Classes\Layout
|
||||
*/
|
||||
public static function initFallback($theme)
|
||||
|
|
|
|||
|
|
@ -216,7 +216,7 @@ class MediaLibrary
|
|||
|
||||
/**
|
||||
* Returns a list of all directories in the Library, optionally excluding some of them.
|
||||
* @param array $exclude A list of folders to exclude from the result list/
|
||||
* @param array $exclude A list of folders to exclude from the result list.
|
||||
* The folder paths should be specified relative to the Library root.
|
||||
* @return array
|
||||
*/
|
||||
|
|
@ -225,21 +225,28 @@ class MediaLibrary
|
|||
$fullPath = $this->getMediaPath('/');
|
||||
|
||||
$folders = $this->getStorageDisk()->allDirectories($fullPath);
|
||||
|
||||
$folders = array_unique($folders, SORT_LOCALE_STRING);
|
||||
|
||||
$result = [];
|
||||
|
||||
foreach ($folders as $folder) {
|
||||
$folder = $this->getMediaRelativePath($folder);
|
||||
if (!strlen($folder))
|
||||
if (!strlen($folder)) {
|
||||
$folder = '/';
|
||||
}
|
||||
|
||||
if (Str::startsWith($folder, $exclude))
|
||||
if (Str::startsWith($folder, $exclude)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$result[] = $folder;
|
||||
}
|
||||
|
||||
if (!in_array('/', $result)) {
|
||||
array_unshift($result, '/');
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
|
@ -333,10 +340,34 @@ class MediaLibrary
|
|||
*/
|
||||
public function moveFolder($originalPath, $newPath)
|
||||
{
|
||||
if (!$this->copyFolder($originalPath, $newPath))
|
||||
return false;
|
||||
if (Str::lower($originalPath) !== Str::lower($newPath)) {
|
||||
// If there is no risk that the directory was renamed
|
||||
// by just changing the letter case in the name -
|
||||
// copy the directory to the destination path and delete
|
||||
// the source directory.
|
||||
|
||||
$this->deleteFolder($originalPath);
|
||||
if (!$this->copyFolder($originalPath, $newPath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->deleteFolder($originalPath);
|
||||
} else {
|
||||
// If there's a risk that the directory name was updated
|
||||
// by changing the letter case - swap source and destination
|
||||
// using a temporary directory with random name.
|
||||
|
||||
$tempraryDirPath = $this->generateRandomTmpFolderName(dirname($originalPath));
|
||||
|
||||
if (!$this->copyFolder($originalPath, $tempraryDirPath)) {
|
||||
$this->deleteFolder($tempraryDirPath);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->deleteFolder($originalPath);
|
||||
|
||||
return $this->moveFolder($tempraryDirPath, $newPath);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -383,8 +414,8 @@ class MediaLibrary
|
|||
return $path;
|
||||
}
|
||||
|
||||
$regexDirectorySeparator = preg_quote(DIRECTORY_SEPARATOR, '/');
|
||||
$regexDot = preg_quote('.', '/');
|
||||
$regexDirectorySeparator = preg_quote('/', '#');
|
||||
$regexDot = preg_quote('.', '#');
|
||||
$regex = [
|
||||
// Checks for parent or current directory reference at beginning of path
|
||||
'(^'.$regexDot.'+?'.$regexDirectorySeparator.')',
|
||||
|
|
@ -399,7 +430,7 @@ class MediaLibrary
|
|||
/*
|
||||
* Combine everything to one regex
|
||||
*/
|
||||
$regex = '/'.implode('|', $regex).'/';
|
||||
$regex = '#'.implode('|', $regex).'#';
|
||||
if (preg_match($regex, $path) !== 0 || strpos($path, '//') !== false) {
|
||||
throw new ApplicationException(Lang::get('cms::lang.media.invalid_path', compact('path')));
|
||||
}
|
||||
|
|
@ -467,7 +498,7 @@ class MediaLibrary
|
|||
/**
|
||||
* Initializes a library item from a path and item type.
|
||||
* @param string $path Specifies the item path relative to the storage disk root.
|
||||
* @param string $type Specifies the item type.
|
||||
* @param string $itemType Specifies the item type.
|
||||
* @return mixed Returns the MediaLibraryItem object or NULL if the item is not visible.
|
||||
*/
|
||||
protected function initLibraryItem($path, $itemType)
|
||||
|
|
@ -636,4 +667,18 @@ class MediaLibrary
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function generateRandomTmpFolderName($location)
|
||||
{
|
||||
$temporaryDirBaseName = time();
|
||||
|
||||
$tmpPath = $location.'/tmp-'.$temporaryDirBaseName;
|
||||
|
||||
while ($this->folderExists($tmpPath)) {
|
||||
$temporaryDirBaseName++;
|
||||
$tmpPath = $location.'/tmp-'.$temporaryDirBaseName;
|
||||
}
|
||||
|
||||
return $tmpPath;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,7 +40,8 @@ class ThemeManager
|
|||
|
||||
/**
|
||||
* Flags a theme as being installed, so it is not downloaded twice.
|
||||
* @param string $name Theme code
|
||||
* @param string $code Theme code
|
||||
* @param string|null $dirName
|
||||
*/
|
||||
public function setInstalled($code, $dirName = null)
|
||||
{
|
||||
|
|
@ -55,7 +56,7 @@ class ThemeManager
|
|||
|
||||
/**
|
||||
* Flags a theme as being uninstalled.
|
||||
* @param string $name Theme code
|
||||
* @param string $code Theme code
|
||||
*/
|
||||
public function setUninstalled($code)
|
||||
{
|
||||
|
|
@ -89,7 +90,7 @@ class ThemeManager
|
|||
|
||||
/**
|
||||
* Completely delete a theme from the system.
|
||||
* @param string $id Theme code/namespace
|
||||
* @param string $theme Theme code/namespace
|
||||
* @return void
|
||||
*/
|
||||
public function deleteTheme($theme)
|
||||
|
|
|
|||
|
|
@ -672,12 +672,12 @@ class MediaManager extends WidgetBase
|
|||
|
||||
protected function setSidebarVisible($visible)
|
||||
{
|
||||
return $this->putSession('sideba_visible', !!$visible);
|
||||
return $this->putSession('sidebar_visible', !!$visible);
|
||||
}
|
||||
|
||||
protected function getSidebarVisible()
|
||||
{
|
||||
return $this->getSession('sideba_visible', true);
|
||||
return $this->getSession('sidebar_visible', true);
|
||||
}
|
||||
|
||||
protected function itemTypeToIconClass($item, $itemType)
|
||||
|
|
@ -703,11 +703,12 @@ class MediaManager extends WidgetBase
|
|||
$folder = array_pop($path);
|
||||
|
||||
$result[$folder] = implode('/', $path).'/'.$folder;
|
||||
if (substr($result[$folder], 0, 1) != '/')
|
||||
if (substr($result[$folder], 0, 1) != '/') {
|
||||
$result[$folder] = '/'.$result[$folder];
|
||||
}
|
||||
}
|
||||
|
||||
return array_reverse($result);
|
||||
return array_reverse($result, true);
|
||||
}
|
||||
|
||||
protected function setViewMode($viewMode)
|
||||
|
|
@ -1028,10 +1029,10 @@ class MediaManager extends WidgetBase
|
|||
/**
|
||||
* Creates a slug form the string. A modified version of Str::slug
|
||||
* with the main difference that it accepts @-signs
|
||||
* @param string
|
||||
* @param string $title
|
||||
* @return string
|
||||
*/
|
||||
protected function cleanFileName($name)
|
||||
protected function cleanFileName($title)
|
||||
{
|
||||
$title = Str::ascii($title);
|
||||
|
||||
|
|
@ -1091,7 +1092,8 @@ class MediaManager extends WidgetBase
|
|||
'url' => $url,
|
||||
'dimensions' => $dimensions
|
||||
];
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// If the target dimensions are provided, resize the original image and return its URL
|
||||
// and dimensions.
|
||||
|
||||
|
|
@ -1115,7 +1117,8 @@ class MediaManager extends WidgetBase
|
|||
'dimensions' => $dimensions
|
||||
];
|
||||
}
|
||||
} catch (Exception $ex) {
|
||||
}
|
||||
catch (Exception $ex) {
|
||||
if ($sessionDirectoryCreated)
|
||||
@File::deleteDirectory($fullSessionDirectoryPath);
|
||||
|
||||
|
|
|
|||
|
|
@ -173,7 +173,9 @@ if($item.data('item-type')=='folder'){if(!$item.data('clear-search'))
|
|||
this.gotoFolder($item.data('path'))
|
||||
else{this.resetSearch()
|
||||
this.gotoFolder($item.data('path'),true)}}
|
||||
else if($item.data('item-type')=='file'){this.$el.trigger('popupcommand',['insert'])}}
|
||||
else if($item.data('item-type')=='file'){var $html=$(document.documentElement)
|
||||
if($html.hasClass('safari')&&!$html.hasClass('chrome')){return}
|
||||
this.$el.trigger('popupcommand',['insert'])}}
|
||||
MediaManager.prototype.isPreviewSidebarVisible=function(){return!this.$el.find('[data-control="preview-sidebar"]').hasClass('hide')}
|
||||
MediaManager.prototype.toggleSidebar=function(ev){var isVisible=this.isPreviewSidebarVisible(),$sidebar=this.$el.find('[data-control="preview-sidebar"]'),$button=$(ev.target)
|
||||
if(!isVisible){$sidebar.removeClass('hide')
|
||||
|
|
|
|||
|
|
@ -414,7 +414,18 @@
|
|||
}
|
||||
else if ($item.data('item-type') == 'file') {
|
||||
// Trigger the Insert popup command if a file item
|
||||
// was double clicked.
|
||||
// was double clicked or Enter key was pressed.
|
||||
|
||||
var $html = $(document.documentElement)
|
||||
if ($html.hasClass('safari') && !$html.hasClass('chrome')) {
|
||||
// Inserting media/link in Safari with Enter key and double click
|
||||
// is buggy. It causes endless recursion inside the rich editor
|
||||
// third-party code.
|
||||
// See https://github.com/octobercms/october/issues/1733
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
this.$el.trigger('popupcommand', ['insert'])
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Table row linking plugin
|
||||
*
|
||||
*
|
||||
* Data attributes:
|
||||
* - data-control="rowlink" - enables the plugin on an element
|
||||
*
|
||||
|
|
@ -36,9 +36,11 @@
|
|||
var href = link.attr('href'),
|
||||
onclick = (typeof link.get(0).onclick == "function") ? link.get(0).onclick : null
|
||||
|
||||
$(this).find('td').not('.' + options.excludeClass).click(function() {
|
||||
$(this).find('td').not('.' + options.excludeClass).click(function(e) {
|
||||
if (onclick)
|
||||
onclick.apply(link.get(0))
|
||||
else if (e.ctrlKey)
|
||||
window.open(href);
|
||||
else
|
||||
window.location = href;
|
||||
})
|
||||
|
|
@ -88,4 +90,4 @@
|
|||
$('[data-control="rowlink"]').rowLink()
|
||||
})
|
||||
|
||||
}(window.jQuery);
|
||||
}(window.jQuery);
|
||||
|
|
|
|||
|
|
@ -175,7 +175,7 @@ class CombineAssets
|
|||
|
||||
$combiner = $this->prepareCombiner($cacheInfo['files']);
|
||||
$contents = $combiner->dump();
|
||||
$mime = ($cacheInfo['extension'] == 'css') ? 'text/css' : 'text/javascript';
|
||||
$mime = ($cacheInfo['extension'] == 'css') ? 'text/css' : 'application/javascript';
|
||||
|
||||
header_remove();
|
||||
$response = Response::make($contents);
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ class MailTemplate extends Model
|
|||
$template = self::make();
|
||||
$template->code = $code;
|
||||
$template->description = $description;
|
||||
$template->is_custom = false;
|
||||
$template->is_custom = 0;
|
||||
$template->layout_id = isset($categories[$layoutCode]) ? $categories[$layoutCode] : null;
|
||||
$template->forceSave();
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue