mirror of
https://github.com/wintercms/winter.git
synced 2024-06-28 05:33:29 +02:00
Merge branch 'develop' into media-manager
This commit is contained in:
commit
9173e3bb9a
@ -1,3 +1,7 @@
|
||||
* **Build 246** (2015-04-21)
|
||||
- Adds experimental command `october:mirror` for generating symbolic links in a public directory.
|
||||
- Various performance improvements.
|
||||
|
||||
* **Build 239** (2015-04-06)
|
||||
- Installing plugins has a new interface and themes can now be installed using the back-end.
|
||||
|
||||
|
@ -6,6 +6,7 @@ use File;
|
||||
use Config;
|
||||
use Illuminate\Routing\Controller as ControllerBase;
|
||||
use October\Rain\Router\Helper as RouterHelper;
|
||||
use Closure;
|
||||
|
||||
/**
|
||||
* The Backend controller class.
|
||||
@ -16,6 +17,13 @@ use October\Rain\Router\Helper as RouterHelper;
|
||||
*/
|
||||
class BackendController extends ControllerBase
|
||||
{
|
||||
use \October\Rain\Extension\ExtendableTrait;
|
||||
|
||||
/**
|
||||
* @var array Behaviors implemented by this controller.
|
||||
*/
|
||||
public $implement;
|
||||
|
||||
/**
|
||||
* @var string Allows early access to page action.
|
||||
*/
|
||||
@ -26,6 +34,22 @@ class BackendController extends ControllerBase
|
||||
*/
|
||||
public static $params;
|
||||
|
||||
/**
|
||||
* Instantiate a new BackendController instance.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->extendableConstruct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Extend this object properties upon construction.
|
||||
*/
|
||||
public static function extend(Closure $callback)
|
||||
{
|
||||
self::extendableExtendCallback($callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds and serves the requested backend controller.
|
||||
* If the controller cannot be found, returns the Cms page with the URL /404.
|
||||
|
@ -292,6 +292,10 @@ class FileUpload extends FormWidgetBase
|
||||
}
|
||||
|
||||
try {
|
||||
if (!Input::hasFile('file_data')) {
|
||||
throw new ApplicationException('File missing from request');
|
||||
}
|
||||
|
||||
$uploadedFile = Input::file('file_data');
|
||||
|
||||
$validationRules = ['max:'.File::getMaxFilesize()];
|
||||
|
49
modules/cms/classes/CmsController.php
Normal file
49
modules/cms/classes/CmsController.php
Normal file
@ -0,0 +1,49 @@
|
||||
<?php namespace Cms\Classes;
|
||||
|
||||
use App;
|
||||
use Illuminate\Routing\Controller as ControllerBase;
|
||||
use Closure;
|
||||
|
||||
/**
|
||||
* The CMS controller class.
|
||||
* The base controller services front end pages.
|
||||
*
|
||||
* @package october\cms
|
||||
* @author Alexey Bobkov, Samuel Georges
|
||||
*/
|
||||
class CmsController extends ControllerBase
|
||||
{
|
||||
use \October\Rain\Extension\ExtendableTrait;
|
||||
|
||||
/**
|
||||
* @var array Behaviors implemented by this controller.
|
||||
*/
|
||||
public $implement;
|
||||
|
||||
/**
|
||||
* Instantiate a new CmsController instance.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->extendableConstruct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Extend this object properties upon construction.
|
||||
*/
|
||||
public static function extend(Closure $callback)
|
||||
{
|
||||
self::extendableExtendCallback($callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds and serves the request using the primary controller.
|
||||
* @param string $url Specifies the requested page URL.
|
||||
* If the parameter is omitted, the current URL used.
|
||||
* @return string Returns the processed page content.
|
||||
*/
|
||||
public function run($url = null)
|
||||
{
|
||||
return App::make('Cms\Classes\Controller')->run($url);
|
||||
}
|
||||
}
|
@ -3,7 +3,7 @@
|
||||
use File;
|
||||
use Twig_Error;
|
||||
use Cms\Classes\SectionParser;
|
||||
use ApplicationException;
|
||||
use October\Rain\Exception\ApplicationException;
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
|
@ -664,7 +664,7 @@ class Controller
|
||||
list($componentName, $handlerName) = explode('::', $handler);
|
||||
$componentObj = $this->findComponentByName($componentName);
|
||||
|
||||
if ($componentObj && method_exists($componentObj, $handlerName)) {
|
||||
if ($componentObj && $componentObj->methodExists($handlerName)) {
|
||||
$this->componentContext = $componentObj;
|
||||
$result = $componentObj->runAjaxHandler($handlerName);
|
||||
return ($result) ?: true;
|
||||
@ -1076,7 +1076,7 @@ class Controller
|
||||
$url = substr($url, 1);
|
||||
}
|
||||
|
||||
$routeAction = 'Cms\Classes\Controller@run';
|
||||
$routeAction = 'Cms\Classes\CmsController@run';
|
||||
$actionExists = Route::getRoutes()->getByAction($routeAction) !== null;
|
||||
|
||||
if ($actionExists) {
|
||||
@ -1288,50 +1288,4 @@ class Controller
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Keep Laravel Happy
|
||||
//
|
||||
|
||||
/**
|
||||
* Get the middleware assigned to the controller.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getMiddleware()
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the registered "before" filters.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getBeforeFilters()
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the registered "after" filters.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAfterFilters()
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute an action on the controller.
|
||||
*
|
||||
* @param string $method
|
||||
* @param array $parameters
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function callAction($method, $parameters)
|
||||
{
|
||||
return call_user_func_array(array($this, $method), $parameters);
|
||||
}
|
||||
}
|
||||
|
@ -308,12 +308,11 @@ class Theme
|
||||
public function getPreviewImageUrl()
|
||||
{
|
||||
$previewPath = '/assets/images/theme-preview.png';
|
||||
$path = $this->getPath().$previewPath;
|
||||
if (!File::exists($path)) {
|
||||
return URL::asset('modules/cms/assets/images/default-theme-preview.png');
|
||||
if (File::exists($this->getPath().$previewPath)) {
|
||||
return URL::asset('themes/'.$this->getDirName().$previewPath);
|
||||
}
|
||||
|
||||
return URL::asset('themes/'.$this->getDirName().$previewPath);
|
||||
return URL::asset('modules/cms/assets/images/default-theme-preview.png');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -8,5 +8,5 @@ App::before(function ($request) {
|
||||
* The CMS module intercepts all URLs that were not
|
||||
* handled by the back-end modules.
|
||||
*/
|
||||
Route::any('{slug}', 'Cms\Classes\Controller@run')->where('slug', '(.*)?');
|
||||
Route::any('{slug}', 'Cms\Classes\CmsController@run')->where('slug', '(.*)?');
|
||||
});
|
||||
|
@ -113,9 +113,12 @@ class DebugExtension extends Twig_Extension
|
||||
elseif (is_array($var)) {
|
||||
$caption = static::ARRAY_CAPTION;
|
||||
}
|
||||
else {
|
||||
elseif (is_object($var)) {
|
||||
$caption = [static::OBJECT_CAPTION, get_class($var)];
|
||||
}
|
||||
else {
|
||||
$caption = [static::OBJECT_CAPTION, gettype($var)];
|
||||
}
|
||||
|
||||
$result .= $this->dump($var, $caption);
|
||||
}
|
||||
@ -443,6 +446,9 @@ class DebugExtension extends Twig_Extension
|
||||
|
||||
$vars = [];
|
||||
foreach ($info->getProperties() as $property) {
|
||||
if ($property->isStatic()) {
|
||||
continue; // Only non-static
|
||||
}
|
||||
if (!$property->isPublic()) {
|
||||
continue; // Only public
|
||||
}
|
||||
|
@ -345,16 +345,17 @@ class ServiceProvider extends ModuleServiceProvider
|
||||
*/
|
||||
protected function registerPrivilegedActions()
|
||||
{
|
||||
$requests = ['/combine', '@/system/updates', '@/backend/auth'];
|
||||
$requests = ['/combine', '@/system/updates', '@/system/install', '@/backend/auth'];
|
||||
$commands = ['october:up', 'october:update'];
|
||||
|
||||
/*
|
||||
* Requests
|
||||
*/
|
||||
$path = RouterHelper::normalizeUrl(Request::path());
|
||||
$backendUri = RouterHelper::normalizeUrl(Config::get('cms.backendUri'));
|
||||
foreach ($requests as $request) {
|
||||
if (substr($request, 0, 1) == '@') {
|
||||
$request = Config::get('cms.backendUri') . substr($request, 1);
|
||||
$request = $backendUri . substr($request, 1);
|
||||
}
|
||||
|
||||
if (stripos($path, $request) === 0) {
|
||||
|
@ -7,6 +7,7 @@
|
||||
margin: 0;
|
||||
padding: 10px 0;
|
||||
overflow: hidden;
|
||||
/* clearfix */
|
||||
}
|
||||
.product-list li button {
|
||||
position: absolute;
|
||||
@ -38,9 +39,6 @@
|
||||
padding-bottom: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.plugin-list li:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
.plugin-list li .image {
|
||||
float: left;
|
||||
margin-right: 15px;
|
||||
@ -61,6 +59,9 @@
|
||||
color: #C03F31;
|
||||
font-weight: 400;
|
||||
}
|
||||
.plugin-list li:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
.theme-list li {
|
||||
float: left;
|
||||
padding: 0;
|
||||
@ -70,11 +71,6 @@
|
||||
background: #fff;
|
||||
position: relative;
|
||||
border-radius: 3px;
|
||||
}
|
||||
.theme-list li:hover {
|
||||
border-color: transparent;
|
||||
}
|
||||
.theme-list li {
|
||||
-webkit-transition: border .2s linear;
|
||||
-moz-transition: border .2s linear;
|
||||
transition: border .2s linear;
|
||||
@ -86,9 +82,6 @@
|
||||
width: 210px;
|
||||
height: 140px;
|
||||
}
|
||||
.theme-list li:hover .image {
|
||||
opacity: 0;
|
||||
}
|
||||
.theme-list li .details {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
@ -97,9 +90,6 @@
|
||||
padding: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.theme-list li:hover .details {
|
||||
opacity: 1;
|
||||
}
|
||||
.theme-list li h4 {
|
||||
padding: 15px 0 0;
|
||||
margin: 0;
|
||||
@ -111,32 +101,34 @@
|
||||
text-transform: uppercase;
|
||||
font-size: 12px;
|
||||
}
|
||||
.theme-list li:hover {
|
||||
border-color: transparent;
|
||||
}
|
||||
.theme-list li:hover .image {
|
||||
opacity: 0;
|
||||
}
|
||||
.theme-list li:hover .details {
|
||||
opacity: 1;
|
||||
}
|
||||
.suggested-products {
|
||||
padding: 0;
|
||||
}
|
||||
.suggested-products .product {
|
||||
padding: 0;
|
||||
}
|
||||
.suggested-products .image {
|
||||
float: left;
|
||||
position: relative;
|
||||
}
|
||||
.suggested-products .image img {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
.suggested-themes .image img {
|
||||
width: 60px;
|
||||
height: 40px;
|
||||
}
|
||||
.suggested-products .image {
|
||||
float: left;
|
||||
position: relative;
|
||||
}
|
||||
.suggested-products .details {
|
||||
margin-left: 50px;
|
||||
padding: 10px 0;
|
||||
}
|
||||
.suggested-themes .details {
|
||||
margin-left: 70px;
|
||||
}
|
||||
.suggested-products .details h5 {
|
||||
margin: 0 0 3px;
|
||||
font-size: 14px;
|
||||
@ -175,6 +167,13 @@
|
||||
.suggested-products a:hover .image img {
|
||||
opacity: .5;
|
||||
}
|
||||
.suggested-themes .image img {
|
||||
width: 60px;
|
||||
height: 40px;
|
||||
}
|
||||
.suggested-themes .details {
|
||||
margin-left: 70px;
|
||||
}
|
||||
/*!
|
||||
* Typeahead
|
||||
*/
|
||||
@ -185,6 +184,24 @@
|
||||
text-align: left;
|
||||
padding-bottom: 15px;
|
||||
}
|
||||
.product-search > i.icon {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 15px;
|
||||
font-size: 24px;
|
||||
margin-top: -20px;
|
||||
color: rgba(0, 0, 0, 0.35);
|
||||
}
|
||||
.product-search > i.icon.loading {
|
||||
display: block;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
background-image: url(../../../../backend/assets/images/loading-indicator-transparent.svg);
|
||||
background-size: 24px 24px;
|
||||
background-position: 50% 50%;
|
||||
-webkit-animation: spin 1s linear infinite;
|
||||
animation: spin 1s linear infinite;
|
||||
}
|
||||
.twitter-typeahead {
|
||||
width: 100%;
|
||||
}
|
||||
|
@ -53,7 +53,21 @@
|
||||
var engine = new Bloodhound({
|
||||
name: 'products',
|
||||
method: 'POST',
|
||||
remote: window.location.pathname + '?search=' + searchType + '&query=%QUERY',
|
||||
remote: {
|
||||
url: window.location.pathname + '?search=' + searchType + '&query=%QUERY',
|
||||
ajax: {
|
||||
beforeSend: function() {
|
||||
$('.icon', $form).hide()
|
||||
$('.icon.loading', $form).show()
|
||||
$el.data('searchReady', false)
|
||||
},
|
||||
complete: function() {
|
||||
$('.icon', $form).show()
|
||||
$('.icon.loading', $form).hide()
|
||||
$el.data('searchReady', true)
|
||||
}
|
||||
}
|
||||
},
|
||||
datumTokenizer: function(d) {
|
||||
return Bloodhound.tokenizers.whitespace(d.val)
|
||||
},
|
||||
@ -92,6 +106,9 @@
|
||||
$el = $(el),
|
||||
$input = $el.find('.product-search-input.tt-input:first')
|
||||
|
||||
if (!$input.data('searchReady'))
|
||||
return
|
||||
|
||||
$el.popup()
|
||||
|
||||
$input.typeahead('val', '')
|
||||
|
@ -205,6 +205,25 @@
|
||||
margin: 0 auto 0 auto;
|
||||
text-align: left;
|
||||
padding-bottom: 15px;
|
||||
|
||||
> i.icon {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 15px;
|
||||
font-size: 24px;
|
||||
margin-top: -20px;
|
||||
color: rgba(0,0,0,.35);
|
||||
}
|
||||
|
||||
> i.icon.loading {
|
||||
display: block;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
background-image: url(../../../../backend/assets/images/loading-indicator-transparent.svg);
|
||||
background-size: 24px 24px;
|
||||
background-position: 50% 50%;
|
||||
.animation(spin 1s linear infinite);
|
||||
}
|
||||
}
|
||||
.twitter-typeahead {
|
||||
width: 100%;
|
||||
@ -247,11 +266,9 @@
|
||||
.tt-suggestion {
|
||||
font-size: 14px;
|
||||
line-height: 18px;
|
||||
+ {
|
||||
.tt-suggestion {
|
||||
font-size: 14px;
|
||||
border-top: 1px solid #ccc;
|
||||
}
|
||||
+ .tt-suggestion {
|
||||
font-size: 14px;
|
||||
border-top: 1px solid #ccc;
|
||||
}
|
||||
}
|
||||
.tt-suggestions {
|
||||
|
@ -210,6 +210,14 @@ class PluginManager
|
||||
View::addNamespace($pluginNamespace, $viewsPath);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add init, if available
|
||||
*/
|
||||
$initFile = $pluginPath . '/init.php';
|
||||
if (!self::$noInit && File::exists($initFile)) {
|
||||
require $initFile;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add routes, if available
|
||||
*/
|
||||
|
@ -14,6 +14,8 @@
|
||||
placeholder="search plugins to install..."
|
||||
data-search-type="plugins"
|
||||
/>
|
||||
<i class="icon icon-search"></i>
|
||||
<i class="icon loading" style="display: none"></i>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
@ -14,6 +14,8 @@
|
||||
placeholder="search themes to install..."
|
||||
data-search-type="themes"
|
||||
/>
|
||||
<i class="icon icon-search"></i>
|
||||
<i class="icon loading" style="display: none"></i>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
@ -23,7 +23,7 @@ return [
|
||||
'ru' => 'Russian',
|
||||
'se' => 'Swedish',
|
||||
'sk' => 'Slovak (Slovakia)',
|
||||
'tr' => 'Turkish'
|
||||
'tr' => 'Turkish',
|
||||
'nb-no' => 'Norwegian (Bokmål)'
|
||||
],
|
||||
'directory' => [
|
||||
|
@ -23,7 +23,7 @@ return [
|
||||
'ru' => 'Russian',
|
||||
'se' => 'Swedish',
|
||||
'sk' => 'Slovak (Slovakia)',
|
||||
'tr' => 'Turkish'
|
||||
'tr' => 'Turkish',
|
||||
'nb-no' => 'Norska (Bokmål)'
|
||||
],
|
||||
'directory' => [
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
use Str;
|
||||
use Model;
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Model for logging system errors and debug trace messages
|
||||
@ -38,7 +39,10 @@ class EventLog extends Model
|
||||
$record->details = (array) $details;
|
||||
}
|
||||
|
||||
$record->save();
|
||||
try {
|
||||
$record->save();
|
||||
}
|
||||
catch (Exception $ex) {}
|
||||
|
||||
return $record;
|
||||
}
|
||||
|
@ -50,7 +50,8 @@ trait ViewMaker
|
||||
public function makePartial($partial, $params = [], $throwException = true)
|
||||
{
|
||||
if (!File::isPathSymbol($partial) && realpath($partial) === false) {
|
||||
$partial = '_' . strtolower($partial) . '.htm';
|
||||
$folder = strpos($partial, '/') !== false ? dirname($partial) . '/' : '';
|
||||
$partial = $folder . '_' . strtolower(basename($partial)).'.htm';
|
||||
}
|
||||
|
||||
$partialPath = $this->getViewPath($partial);
|
||||
@ -136,7 +137,8 @@ trait ViewMaker
|
||||
public function makeLayoutPartial($partial, $params = [])
|
||||
{
|
||||
if (!File::isLocalPath($partial) && !File::isPathSymbol($partial)) {
|
||||
$partial = '_' . strtolower($partial);
|
||||
$folder = strpos($partial, '/') !== false ? dirname($partial) . '/' : '';
|
||||
$partial = $folder . '_' . strtolower(basename($partial));
|
||||
}
|
||||
|
||||
return $this->makeLayout($partial, $params);
|
||||
|
Loading…
x
Reference in New Issue
Block a user