diff --git a/modules/backend/behaviors/ListController.php b/modules/backend/behaviors/ListController.php index 91baff00c..9882bb7ad 100644 --- a/modules/backend/behaviors/ListController.php +++ b/modules/backend/behaviors/ListController.php @@ -241,6 +241,13 @@ class ListController extends ControllerBehavior return $widget->onRefresh(); }); + /* + * Filter Widget with extensibility + */ + $filterWidget->bindEvent('filter.extendScopes', function () use ($filterWidget) { + $this->controller->listFilterExtendScopes($filterWidget); + }); + /* * Extend the query of the list of options */ @@ -449,6 +456,15 @@ class ListController extends ControllerBehavior public function listExtendColumns($host) { } + + /** + * Called after the filter scopes are defined. + * @param \Backend\Widgets\Filter $host The hosting filter widget + * @return void + */ + public function listFilterExtendScopes($host) + { + } /** * Controller override: Extend supplied model @@ -543,4 +559,20 @@ class ListController extends ControllerBehavior call_user_func_array($callback, [$widget, $widget->model]); }); } + + /** + * Static helper for extending filter scopes. + * @param callable $callback + * @return void + */ + public static function extendListFilterScopes($callback) + { + $calledClass = self::getCalledExtensionClass(); + Event::listen('backend.filter.extendScopes', function ($widget) use ($calledClass, $callback) { + if (!is_a($widget->getController(), $calledClass)) { + return; + } + call_user_func_array($callback, [$widget]); + }); + } } diff --git a/modules/backend/formwidgets/repeater/partials/_repeater.htm b/modules/backend/formwidgets/repeater/partials/_repeater.htm index 7c5d6611b..79cea1e78 100644 --- a/modules/backend/formwidgets/repeater/partials/_repeater.htm +++ b/modules/backend/formwidgets/repeater/partials/_repeater.htm @@ -53,8 +53,8 @@ data-request="getEventHandler('onAddItem') ?>" data-request-data="_repeater_group: ''"> - - + + @@ -67,4 +67,4 @@ - \ No newline at end of file + diff --git a/modules/cms/classes/ComponentBase.php b/modules/cms/classes/ComponentBase.php index 8ccdcd949..9546cd4c0 100644 --- a/modules/cms/classes/ComponentBase.php +++ b/modules/cms/classes/ComponentBase.php @@ -260,7 +260,7 @@ abstract class ComponentBase extends Extendable public function __call($method, $parameters) { try { - parent::__call($method, $parameters); + return parent::__call($method, $parameters); } catch (BadMethodCallException $ex) {} diff --git a/modules/cms/classes/Page.php b/modules/cms/classes/Page.php index f3fb1879f..c9cb2d0ea 100644 --- a/modules/cms/classes/Page.php +++ b/modules/cms/classes/Page.php @@ -4,6 +4,7 @@ use Lang; use Cms\Classes\Theme; use Cms\Classes\Layout; use ApplicationException; +use October\Rain\Filesystem\Definitions as FileDefinitions; /** * The CMS page class. @@ -88,8 +89,14 @@ class Page extends CmsCompoundObject $layouts = Layout::listInTheme($theme, true); $result = []; $result[null] = Lang::get('cms::lang.page.no_layout'); + foreach ($layouts as $layout) { $baseName = $layout->getBaseFileName(); + + if (FileDefinitions::isPathIgnored($baseName)) { + continue; + } + $result[$baseName] = strlen($layout->name) ? $layout->name : $baseName; } diff --git a/modules/cms/lang/en/lang.php b/modules/cms/lang/en/lang.php index 7bab451cc..3ca8cc453 100644 --- a/modules/cms/lang/en/lang.php +++ b/modules/cms/lang/en/lang.php @@ -284,7 +284,7 @@ return [ 'size' => 'Size', 'title' => 'Title', 'last_modified' => 'Last modified', - 'public_url' => 'Public URL', + 'public_url' => 'Download URL', 'click_here' => 'Click here', 'thumbnail_error' => 'Error generating thumbnail.', 'return_to_parent' => 'Return to the parent folder', @@ -310,7 +310,7 @@ return [ 'move_destination' => 'Destination folder', 'please_select_move_dest' => 'Please select a destination folder.', 'move_dest_src_match' => 'Please select another destination folder.', - 'empty_library' => 'The Media Library is empty. Upload files or create folders to get started.', + 'empty_library' => 'It looks a bit empty here. Upload files or create folders to get started.', 'insert' => 'Insert', 'crop_and_insert' => 'Crop & Insert', 'select_single_image' => 'Please select a single image.', diff --git a/modules/cms/models/ThemeData.php b/modules/cms/models/ThemeData.php index dde92f731..1dd99f8b5 100644 --- a/modules/cms/models/ThemeData.php +++ b/modules/cms/models/ThemeData.php @@ -154,7 +154,7 @@ class ThemeData extends Model $result = []; foreach ($this->getFormFields() as $attribute => $field) { - if (!$value = array_get($field, 'default')) { + if (($value = array_get($field, 'default')) === null) { continue; } diff --git a/modules/cms/widgets/MediaManager.php b/modules/cms/widgets/MediaManager.php index 2bbbdee07..5d863c14e 100644 --- a/modules/cms/widgets/MediaManager.php +++ b/modules/cms/widgets/MediaManager.php @@ -6,6 +6,7 @@ use Lang; use File; use Form; use Input; +use Config; use Request; use Response; use Exception; @@ -872,7 +873,9 @@ class MediaManager extends WidgetBase { $fileName = md5($fileName.uniqid().microtime()); - $path = temp_path() . '/media'; + $mediaFolder = Config::get('cms.storage.media.folder', 'media'); + + $path = temp_path() . MediaLibrary::validatePath($mediaFolder, true); if (!File::isDirectory($path)) { File::makeDirectory($path, 0777, true, true); @@ -883,7 +886,11 @@ class MediaManager extends WidgetBase protected function getThumbnailDirectory() { - return '/public/'; + /* + * NOTE: Custom routing for /storage/temp/$thumbnailDirectory must be setup + * to return the thumbnail if not using default 'public' directory + */ + return MediaLibrary::validatePath(Config::get('cms.storage.media.thumbFolder', 'public'), true) . '/'; } protected function getPlaceholderId($item) diff --git a/modules/cms/widgets/mediamanager/assets/js/mediamanager-browser-min.js b/modules/cms/widgets/mediamanager/assets/js/mediamanager-browser-min.js index 6dd38823d..993855a1b 100644 --- a/modules/cms/widgets/mediamanager/assets/js/mediamanager-browser-min.js +++ b/modules/cms/widgets/mediamanager/assets/js/mediamanager-browser-min.js @@ -343,7 +343,8 @@ $.oc.confirm(this.options.deleteConfirm,this.proxy(this.deleteConfirmation))} MediaManager.prototype.deleteConfirmation=function(confirmed){if(!confirmed) return var items=this.$el.get(0).querySelectorAll('[data-type="media-item"].selected'),paths=[] -for(var i=0,len=items.length;i= 0; i--) this.thumbnailQueue.push({ id: placeholders[i].getAttribute('id'), - width: placeholders[i].getAttribute('data-width'), - height: placeholders[i].getAttribute('data-height'), + width: placeholders[i].getAttribute('data-width'), + height: placeholders[i].getAttribute('data-height'), path: placeholders[i].getAttribute('data-path'), lastModified: placeholders[i].getAttribute('data-last-modified') }) @@ -919,6 +919,10 @@ paths = [] for (var i=0, len=items.length; i 2 || Math.abs(deltaY) > 2)) { - // Start processing the selection only if the mouse was moved by + // Start processing the selection only if the mouse was moved by // at least 2 pixels. this.createSelectionMarker() @@ -1209,20 +1213,20 @@ if (this.selectionStarted) { if (deltaX >= 0) { - this.selectionMarker.style.left = this.selectionStartPoint.x + 'px' - this.selectionMarker.style.width = deltaX + 'px' + this.selectionMarker.style.left = this.selectionStartPoint.x + 'px' + this.selectionMarker.style.width = deltaX + 'px' } else { - this.selectionMarker.style.left = relativePosition.x + 'px' - this.selectionMarker.style.width = Math.abs(deltaX) + 'px' + this.selectionMarker.style.left = relativePosition.x + 'px' + this.selectionMarker.style.width = Math.abs(deltaX) + 'px' } if (deltaY >= 0) { - this.selectionMarker.style.height = deltaY + 'px' + this.selectionMarker.style.height = deltaY + 'px' this.selectionMarker.style.top = this.selectionStartPoint.y + 'px' } else { - this.selectionMarker.style.top = relativePosition.y + 'px' + this.selectionMarker.style.top = relativePosition.y + 'px' this.selectionMarker.style.height = Math.abs(deltaY) + 'px' } } @@ -1285,7 +1289,7 @@ var old = $.fn.mediaManager $.fn.mediaManager = function (option) { - var args = Array.prototype.slice.call(arguments, 1), + var args = Array.prototype.slice.call(arguments, 1), result = undefined this.each(function () { @@ -1296,7 +1300,7 @@ if (typeof option == 'string') result = data[option].apply(data, args) if (typeof result != 'undefined') return false }) - + return result ? result : this } @@ -1317,4 +1321,4 @@ $('div[data-control=media-manager]').mediaManager() }) -}(window.jQuery); \ No newline at end of file +}(window.jQuery); diff --git a/modules/system/classes/UpdateManager.php b/modules/system/classes/UpdateManager.php index ecaa3bbd9..7a6c20af8 100644 --- a/modules/system/classes/UpdateManager.php +++ b/modules/system/classes/UpdateManager.php @@ -31,11 +31,15 @@ class UpdateManager use \October\Rain\Support\Traits\Singleton; /** - * The notes for the current operation. - * @var array + * @var array The notes for the current operation. */ protected $notes = []; + /** + * @var \Illuminate\Console\OutputStyle + */ + protected $notesOutput; + /** * @var string Application base path. */ @@ -376,9 +380,11 @@ class UpdateManager $this->migrator->run(base_path() . '/modules/'.strtolower($module).'/database/migrations'); $this->note($module); + foreach ($this->migrator->getNotes() as $note) { $this->note(' - '.$note); } + return $this; } @@ -477,13 +483,17 @@ class UpdateManager return; } - $this->versionManager->resetNotes(); + $this->note($name); + + $this->versionManager->resetNotes()->setNotesOutput($this->notesOutput); + if ($this->versionManager->updatePlugin($plugin) !== false) { - $this->note($name); + foreach ($this->versionManager->getNotes() as $note) { - $this->note(' - '.$note); + $this->note($note); } } + return $this; } @@ -700,11 +710,17 @@ class UpdateManager /** * Raise a note event for the migrator. * @param string $message - * @return void + * @return self */ protected function note($message) { - $this->notes[] = $message; + if ($this->notesOutput !== null) { + $this->notesOutput->writeln($message); + } + else { + $this->notes[] = $message; + } + return $this; } @@ -719,11 +735,26 @@ class UpdateManager /** * Resets the notes store. - * @return array + * @return self */ public function resetNotes() { + $this->notesOutput = null; + $this->notes = []; + + return $this; + } + + /** + * Sets an output stream for writing notes. + * @param Illuminate\Console\Command $output + * @return self + */ + public function setNotesOutput($output) + { + $this->notesOutput = $output; + return $this; } diff --git a/modules/system/classes/VersionManager.php b/modules/system/classes/VersionManager.php index 1e40beb7c..3e355d264 100644 --- a/modules/system/classes/VersionManager.php +++ b/modules/system/classes/VersionManager.php @@ -36,6 +36,11 @@ class VersionManager */ protected $notes = []; + /** + * @var \Illuminate\Console\OutputStyle + */ + protected $notesOutput; + /** * Cache of plugin versions as files. */ @@ -85,7 +90,7 @@ class VersionManager // No updates needed if ($currentVersion == $databaseVersion) { - $this->note('Nothing to update.'); + $this->note('- Nothing to update.'); return; } @@ -150,7 +155,7 @@ class VersionManager $this->setDatabaseVersion($code, $version); - $this->note(sprintf('v%s: %s', $version, $comment)); + $this->note(sprintf('- v%s: %s', $version, $comment)); } /** @@ -475,7 +480,13 @@ class VersionManager */ protected function note($message) { - $this->notes[] = $message; + if ($this->notesOutput !== null) { + $this->notesOutput->writeln($message); + } + else { + $this->notes[] = $message; + } + return $this; } @@ -490,11 +501,26 @@ class VersionManager /** * Resets the notes store. - * @return array + * @return self */ public function resetNotes() { + $this->notesOutput = null; + $this->notes = []; + + return $this; + } + + /** + * Sets an output stream for writing notes. + * @param Illuminate\Console\Command $output + * @return self + */ + public function setNotesOutput($output) + { + $this->notesOutput = $output; + return $this; } } diff --git a/modules/system/console/OctoberDown.php b/modules/system/console/OctoberDown.php index acb7595cd..fbaf42997 100644 --- a/modules/system/console/OctoberDown.php +++ b/modules/system/console/OctoberDown.php @@ -15,7 +15,6 @@ use Symfony\Component\Console\Input\InputArgument; */ class OctoberDown extends Command { - use \Illuminate\Console\ConfirmableTrait; /** @@ -45,11 +44,10 @@ class OctoberDown extends Command return; } - $manager = UpdateManager::instance()->resetNotes()->uninstall(); - - foreach ($manager->getNotes() as $note) { - $this->output->writeln($note); - } + UpdateManager::instance() + ->setNotesOutput($this->output) + ->uninstall() + ; } /** diff --git a/modules/system/console/OctoberInstall.php b/modules/system/console/OctoberInstall.php index 31badc7fa..4554a3f60 100644 --- a/modules/system/console/OctoberInstall.php +++ b/modules/system/console/OctoberInstall.php @@ -291,7 +291,11 @@ class OctoberInstall extends Command try { Db::purge(); - UpdateManager::instance()->resetNotes()->update(); + + UpdateManager::instance() + ->setNotesOutput($this->output) + ->update() + ; } catch (Exception $ex) { $this->error($ex->getMessage()); diff --git a/modules/system/console/OctoberUp.php b/modules/system/console/OctoberUp.php index b5a02e17a..bce7b1506 100644 --- a/modules/system/console/OctoberUp.php +++ b/modules/system/console/OctoberUp.php @@ -15,7 +15,6 @@ use Symfony\Component\Console\Input\InputArgument; */ class OctoberUp extends Command { - /** * The console command name. */ @@ -39,13 +38,12 @@ class OctoberUp extends Command */ public function fire() { - $manager = UpdateManager::instance()->resetNotes()->update(); - $this->output->writeln('Migrating application and plugins...'); - foreach ($manager->getNotes() as $note) { - $this->output->writeln($note); - } + UpdateManager::instance() + ->setNotesOutput($this->output) + ->update() + ; } /** diff --git a/modules/system/console/OctoberUpdate.php b/modules/system/console/OctoberUpdate.php index 7a40e7214..b5186c5e7 100644 --- a/modules/system/console/OctoberUpdate.php +++ b/modules/system/console/OctoberUpdate.php @@ -44,7 +44,7 @@ class OctoberUpdate extends Command public function fire() { $this->output->writeln('Updating October...'); - $manager = UpdateManager::instance()->resetNotes(); + $manager = UpdateManager::instance()->setNotesOutput($this->output); $forceUpdate = $this->option('force'); /* @@ -66,7 +66,7 @@ class OctoberUpdate extends Command * Perform update */ $updateList = $manager->requestUpdateList($forceUpdate); - $updates = (int)array_get($updateList, 'update', 0); + $updates = (int) array_get($updateList, 'update', 0); if ($updates == 0) { $this->output->writeln('No new updates found'); diff --git a/modules/system/console/PluginInstall.php b/modules/system/console/PluginInstall.php index 546c1cab9..49e62f40d 100644 --- a/modules/system/console/PluginInstall.php +++ b/modules/system/console/PluginInstall.php @@ -45,7 +45,7 @@ class PluginInstall extends Command public function fire() { $pluginName = $this->argument('name'); - $manager = UpdateManager::instance()->resetNotes(); + $manager = UpdateManager::instance()->setNotesOutput($this->output); $pluginDetails = $manager->requestPluginDetails($pluginName); @@ -64,10 +64,6 @@ class PluginInstall extends Command $this->output->writeln(sprintf('Migrating plugin...', $code)); PluginManager::instance()->loadPlugins(); $manager->updatePlugin($code); - - foreach ($manager->getNotes() as $note) { - $this->output->writeln($note); - } } /** diff --git a/modules/system/console/PluginRefresh.php b/modules/system/console/PluginRefresh.php index 7358e1729..5888da71a 100644 --- a/modules/system/console/PluginRefresh.php +++ b/modules/system/console/PluginRefresh.php @@ -45,26 +45,27 @@ class PluginRefresh extends Command */ public function fire() { + /* + * Lookup plugin + */ $pluginName = $this->argument('name'); $pluginName = PluginManager::instance()->normalizeIdentifier($pluginName); if (!PluginManager::instance()->exists($pluginName)) { throw new \InvalidArgumentException(sprintf('Plugin "%s" not found.', $pluginName)); } - $manager = UpdateManager::instance()->resetNotes(); + $manager = UpdateManager::instance()->setNotesOutput($this->output); + /* + * Rollback plugin + */ $manager->rollbackPlugin($pluginName); - foreach ($manager->getNotes() as $note) { - $this->output->writeln($note); - } - $manager->resetNotes(); + /* + * Update plugin + */ $this->output->writeln('Reinstalling plugin...'); $manager->updatePlugin($pluginName); - - foreach ($manager->getNotes() as $note) { - $this->output->writeln($note); - } } /** diff --git a/modules/system/console/PluginRemove.php b/modules/system/console/PluginRemove.php index df2d743c4..e256f3938 100644 --- a/modules/system/console/PluginRemove.php +++ b/modules/system/console/PluginRemove.php @@ -63,13 +63,9 @@ class PluginRemove extends Command /* * Rollback plugin */ - $manager = UpdateManager::instance()->resetNotes(); + $manager = UpdateManager::instance()->setNotesOutput($this->output); $manager->rollbackPlugin($pluginName); - foreach ($manager->getNotes() as $note) { - $this->output->writeln($note); - } - /* * Delete from file system */ diff --git a/modules/system/lang/en/lang.php b/modules/system/lang/en/lang.php index b227f541e..d04cab1ad 100644 --- a/modules/system/lang/en/lang.php +++ b/modules/system/lang/en/lang.php @@ -25,7 +25,8 @@ return [ 'id' => 'Bahasa Indonesia', 'it' => 'Italiano', 'ja' => '日本語', - 'lv' => 'Latvijas', + 'lt' => 'Lietuvių', + 'lv' => 'Latviešu', 'nb-no' => 'Norsk (Bokmål)', 'nl' => 'Nederlands', 'pl' => 'Polskie',