mirror of
https://github.com/wintercms/winter.git
synced 2024-06-28 05:33:29 +02:00
Merge branch 'develop' of github.com:octobercms/october into develop
This commit is contained in:
commit
a4ab611228
@ -15,15 +15,14 @@
|
|||||||
## Black list protected files
|
## Black list protected files
|
||||||
##
|
##
|
||||||
RewriteRule ^themes/.*/(layouts|pages|partials)/.*.htm index.php [L,NC]
|
RewriteRule ^themes/.*/(layouts|pages|partials)/.*.htm index.php [L,NC]
|
||||||
RewriteRule ^uploads/protected/.* index.php [L,NC]
|
|
||||||
RewriteRule ^bootstrap/.* index.php [L,NC]
|
RewriteRule ^bootstrap/.* index.php [L,NC]
|
||||||
RewriteRule ^config/.* index.php [L,NC]
|
RewriteRule ^config/.* index.php [L,NC]
|
||||||
RewriteRule ^vendor/.* index.php [L,NC]
|
RewriteRule ^vendor/.* index.php [L,NC]
|
||||||
RewriteRule ^storage/cms/.* index.php [L,NC]
|
RewriteRule ^storage/cms/.* index.php [L,NC]
|
||||||
RewriteRule ^storage/logs/.* index.php [L,NC]
|
RewriteRule ^storage/logs/.* index.php [L,NC]
|
||||||
RewriteCond %{REQUEST_URI} !storage/temp/public
|
|
||||||
RewriteRule ^storage/temp/.* index.php [L,NC]
|
|
||||||
RewriteRule ^storage/framework/.* index.php [L,NC]
|
RewriteRule ^storage/framework/.* index.php [L,NC]
|
||||||
|
RewriteRule ^storage/temp/protected/.* index.php [L,NC]
|
||||||
|
RewriteRule ^storage/app/uploads/protected/.* index.php [L,NC]
|
||||||
|
|
||||||
##
|
##
|
||||||
## White listed folders and files
|
## White listed folders and files
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
* **Build 24x** (2015-04-xx)
|
||||||
|
- Protected files can now be downloaded by administrators using the `fileupload` form widget.
|
||||||
|
- The `{% content %}` tag now supports passing parameters, parsed by a basic template engine (see Cms > Content block docs).
|
||||||
|
|
||||||
* **Build 247** (2015-04-23)
|
* **Build 247** (2015-04-23)
|
||||||
- Added Media Manager feature.
|
- Added Media Manager feature.
|
||||||
|
|
||||||
|
67
modules/backend/controllers/Files.php
Normal file
67
modules/backend/controllers/Files.php
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
<?php namespace Backend\Controllers;
|
||||||
|
|
||||||
|
use App;
|
||||||
|
use Backend;
|
||||||
|
use System\Models\File as FileModel;
|
||||||
|
use Backend\Classes\Controller;
|
||||||
|
use ApplicationException;
|
||||||
|
use Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Backend files controller
|
||||||
|
*
|
||||||
|
* @package october\backend
|
||||||
|
* @author Alexey Bobkov, Samuel Georges
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class Files extends Controller
|
||||||
|
{
|
||||||
|
public function get($code = null)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
if (!$code) {
|
||||||
|
throw new ApplicationException('Missing code');
|
||||||
|
}
|
||||||
|
|
||||||
|
$parts = explode('!', base64_decode($code));
|
||||||
|
if (count($parts) < 2) {
|
||||||
|
throw new ApplicationException('Invalid code');
|
||||||
|
}
|
||||||
|
|
||||||
|
list($id, $hash) = $parts;
|
||||||
|
|
||||||
|
if (!$file = FileModel::find((int) $id)) {
|
||||||
|
throw new ApplicationException('Unable to find file');
|
||||||
|
}
|
||||||
|
|
||||||
|
$verifyCode = self::getUniqueCode($file);
|
||||||
|
if ($code != $verifyCode) {
|
||||||
|
throw new ApplicationException('Invalid hash');
|
||||||
|
}
|
||||||
|
|
||||||
|
echo $file->output();
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
catch (Exception $ex) {}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fall back on Cms controller
|
||||||
|
*/
|
||||||
|
return App::make('Cms\Classes\Controller')->setStatusCode(404)->run('/404');
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getDownloadUrl($file)
|
||||||
|
{
|
||||||
|
return Backend::url('backend/files/get/' . self::getUniqueCode($file));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getUniqueCode($file)
|
||||||
|
{
|
||||||
|
if (!$file) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$hash = md5($file->file_name . '!' . $file->disk_name);
|
||||||
|
return base64_encode($file->id . '!' . $hash);
|
||||||
|
}
|
||||||
|
}
|
@ -94,7 +94,7 @@ class FileUpload extends FormWidgetBase
|
|||||||
/**
|
/**
|
||||||
* Prepares the view data
|
* Prepares the view data
|
||||||
*/
|
*/
|
||||||
public function prepareVars()
|
protected function prepareVars()
|
||||||
{
|
{
|
||||||
$this->vars['fileList'] = $this->getFileList();
|
$this->vars['fileList'] = $this->getFileList();
|
||||||
$this->vars['singleFile'] = array_get($this->vars['fileList'], 0, null);
|
$this->vars['singleFile'] = array_get($this->vars['fileList'], 0, null);
|
||||||
@ -107,14 +107,19 @@ class FileUpload extends FormWidgetBase
|
|||||||
|
|
||||||
protected function getFileList()
|
protected function getFileList()
|
||||||
{
|
{
|
||||||
$list = $this->getRelationObject()->withDeferred($this->sessionKey)->orderBy('sort_order')->get();
|
$list = $this
|
||||||
|
->getRelationObject()
|
||||||
|
->withDeferred($this->sessionKey)
|
||||||
|
->orderBy('sort_order')
|
||||||
|
->get()
|
||||||
|
;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set the thumb for each file
|
* Decorate each file with thumb and custom download path
|
||||||
*/
|
*/
|
||||||
foreach ($list as $file) {
|
$list->each(function($file){
|
||||||
$file->thumb = $file->getThumb($this->imageWidth, $this->imageHeight, $this->thumbOptions);
|
$this->decorateFileAttributes($file);
|
||||||
}
|
});
|
||||||
|
|
||||||
return $list;
|
return $list;
|
||||||
}
|
}
|
||||||
@ -325,8 +330,7 @@ class FileUpload extends FormWidgetBase
|
|||||||
|
|
||||||
$fileRelation->add($file, $this->sessionKey);
|
$fileRelation->add($file, $this->sessionKey);
|
||||||
|
|
||||||
$file->thumb = $file->getThumb($this->imageWidth, $this->imageHeight, $this->thumbOptions);
|
$result = $this->decorateFileAttributes($file);
|
||||||
$result = $file;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception $ex) {
|
catch (Exception $ex) {
|
||||||
@ -336,4 +340,20 @@ class FileUpload extends FormWidgetBase
|
|||||||
header('Content-Type: application/json');
|
header('Content-Type: application/json');
|
||||||
die($result);
|
die($result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the bespoke thumb and path property used by this widget.
|
||||||
|
* @return System\Models\File
|
||||||
|
*/
|
||||||
|
protected function decorateFileAttributes($file)
|
||||||
|
{
|
||||||
|
$file->thumb = $file->getThumb($this->imageWidth, $this->imageHeight, $this->thumbOptions);
|
||||||
|
|
||||||
|
// Internal download link
|
||||||
|
if (!$file->isImage() || !$file->isPublic()) {
|
||||||
|
$file->path = \Backend\Controllers\Files::getDownloadUrl($file);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $file;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,7 @@
|
|||||||
|
|
||||||
<a
|
<a
|
||||||
href="{{path}}"
|
href="{{path}}"
|
||||||
class="uploader-file-link oc-icon-paper-clip"
|
class="uploader-file-link oc-icon-paperclip"
|
||||||
target="_blank"></a>
|
target="_blank"></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -28,6 +28,7 @@ use October\Rain\Exception\AjaxException;
|
|||||||
use October\Rain\Exception\SystemException;
|
use October\Rain\Exception\SystemException;
|
||||||
use October\Rain\Exception\ValidationException;
|
use October\Rain\Exception\ValidationException;
|
||||||
use October\Rain\Exception\ApplicationException;
|
use October\Rain\Exception\ApplicationException;
|
||||||
|
use October\Rain\Parse\Template as TextParser;
|
||||||
use Illuminate\Http\RedirectResponse;
|
use Illuminate\Http\RedirectResponse;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -894,8 +895,11 @@ class Controller
|
|||||||
/**
|
/**
|
||||||
* Renders a requested content file.
|
* Renders a requested content file.
|
||||||
* The framework uses this method internally.
|
* The framework uses this method internally.
|
||||||
|
* @param string $name The content view to load.
|
||||||
|
* @param array $parameters Parameter variables to pass to the view.
|
||||||
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function renderContent($name)
|
public function renderContent($name, $parameters = [])
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Extensibility
|
* Extensibility
|
||||||
@ -915,6 +919,13 @@ class Controller
|
|||||||
|
|
||||||
$fileContent = $content->parsedMarkup;
|
$fileContent = $content->parsedMarkup;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Parse basic template variables
|
||||||
|
*/
|
||||||
|
if (!empty($parameters)) {
|
||||||
|
$fileContent = TextParser::parse($fileContent, $parameters);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Extensibility
|
* Extensibility
|
||||||
*/
|
*/
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
<?php namespace Cms\Twig;
|
<?php namespace Cms\Twig;
|
||||||
|
|
||||||
use Twig_Node;
|
use Twig_Node;
|
||||||
use Twig_Node_Expression;
|
|
||||||
use Twig_Compiler;
|
use Twig_Compiler;
|
||||||
|
use Twig_NodeInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a content node
|
* Represents a content node
|
||||||
@ -12,9 +12,9 @@ use Twig_Compiler;
|
|||||||
*/
|
*/
|
||||||
class ContentNode extends Twig_Node
|
class ContentNode extends Twig_Node
|
||||||
{
|
{
|
||||||
public function __construct(Twig_Node_Expression $name, $lineno, $tag = 'content')
|
public function __construct(Twig_NodeInterface $nodes, $paramNames, $lineno, $tag = 'content')
|
||||||
{
|
{
|
||||||
parent::__construct(['name' => $name], [], $lineno, $tag);
|
parent::__construct(['nodes' => $nodes], ['names' => $paramNames], $lineno, $tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -24,11 +24,25 @@ class ContentNode extends Twig_Node
|
|||||||
*/
|
*/
|
||||||
public function compile(Twig_Compiler $compiler)
|
public function compile(Twig_Compiler $compiler)
|
||||||
{
|
{
|
||||||
|
$compiler->addDebugInfo($this);
|
||||||
|
|
||||||
|
$compiler->write("\$context['__cms_content_params'] = [];\n");
|
||||||
|
|
||||||
|
for ($i = 1; $i < count($this->getNode('nodes')); $i++) {
|
||||||
|
$compiler->write("\$context['__cms_content_params']['".$this->getAttribute('names')[$i-1]."'] = ");
|
||||||
|
$compiler->write('twig_escape_filter($this->env, ');
|
||||||
|
$compiler->subcompile($this->getNode('nodes')->getNode($i));
|
||||||
|
$compiler->write(")");
|
||||||
|
$compiler->write(";\n");
|
||||||
|
}
|
||||||
|
|
||||||
$compiler
|
$compiler
|
||||||
->addDebugInfo($this)
|
|
||||||
->write("echo \$this->env->getExtension('CMS')->contentFunction(")
|
->write("echo \$this->env->getExtension('CMS')->contentFunction(")
|
||||||
->subcompile($this->getNode('name'))
|
->subcompile($this->getNode('nodes')->getNode(0))
|
||||||
|
->write(", \$context['__cms_content_params']")
|
||||||
->write(");\n")
|
->write(");\n")
|
||||||
;
|
;
|
||||||
|
|
||||||
|
$compiler->write("unset(\$context['__cms_content_params']);\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,19 @@
|
|||||||
<?php namespace Cms\Twig;
|
<?php namespace Cms\Twig;
|
||||||
|
|
||||||
|
use Twig_Node;
|
||||||
use Twig_Token;
|
use Twig_Token;
|
||||||
use Twig_TokenParser;
|
use Twig_TokenParser;
|
||||||
|
use Twig_Error_Syntax;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parser for the {% content %} Twig tag.
|
* Parser for the {% content %} Twig tag.
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* {% content "intro.htm" %}
|
* {% content "intro.htm" %}
|
||||||
|
*
|
||||||
|
* {% content "intro.md" name='John' %}
|
||||||
|
*
|
||||||
|
* {% content "intro/txt" name='John', year=2013 %}
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @package october\cms
|
* @package october\cms
|
||||||
@ -24,10 +30,39 @@ class ContentTokenParser extends Twig_TokenParser
|
|||||||
*/
|
*/
|
||||||
public function parse(Twig_Token $token)
|
public function parse(Twig_Token $token)
|
||||||
{
|
{
|
||||||
|
$lineno = $token->getLine();
|
||||||
$stream = $this->parser->getStream();
|
$stream = $this->parser->getStream();
|
||||||
|
|
||||||
$name = $this->parser->getExpressionParser()->parseExpression();
|
$name = $this->parser->getExpressionParser()->parseExpression();
|
||||||
$stream->expect(Twig_Token::BLOCK_END_TYPE);
|
$paramNames = [];
|
||||||
return new ContentNode($name, $token->getLine(), $this->getTag());
|
$nodes = [$name];
|
||||||
|
|
||||||
|
$end = false;
|
||||||
|
while (!$end) {
|
||||||
|
$current = $stream->next();
|
||||||
|
|
||||||
|
switch ($current->getType()) {
|
||||||
|
case Twig_Token::NAME_TYPE:
|
||||||
|
$paramNames[] = $current->getValue();
|
||||||
|
$stream->expect(Twig_Token::OPERATOR_TYPE, '=');
|
||||||
|
$nodes[] = $this->parser->getExpressionParser()->parseExpression();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Twig_Token::BLOCK_END_TYPE:
|
||||||
|
$end = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new Twig_Error_Syntax(
|
||||||
|
sprintf('Invalid syntax in the content tag. Line %s', $lineno),
|
||||||
|
$stream->getCurrent()->getLine(),
|
||||||
|
$stream->getFilename()
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ContentNode(new Twig_Node($nodes), $paramNames, $token->getLine(), $this->getTag());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -118,11 +118,13 @@ class Extension extends Twig_Extension
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Renders a content file.
|
* Renders a content file.
|
||||||
|
* @param string $name Specifies the content block name.
|
||||||
|
* @param array $parameters A optional list of parameters to pass to the content.
|
||||||
* @return string Returns the file contents.
|
* @return string Returns the file contents.
|
||||||
*/
|
*/
|
||||||
public function contentFunction($name)
|
public function contentFunction($name, $parameters = [])
|
||||||
{
|
{
|
||||||
return $this->controller->renderContent($name);
|
return $this->controller->renderContent($name, $parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -296,14 +296,14 @@ class Updates extends Controller
|
|||||||
$core = [null, null];
|
$core = [null, null];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_array($plugins)) {
|
|
||||||
$plugins = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!is_array($themes)) {
|
if (!is_array($themes)) {
|
||||||
$themes = [];
|
$themes = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!is_array($plugins)) {
|
||||||
|
$plugins = [];
|
||||||
|
}
|
||||||
|
|
||||||
$updateSteps = [];
|
$updateSteps = [];
|
||||||
list($coreHash, $coreBuild) = $core;
|
list($coreHash, $coreBuild) = $core;
|
||||||
|
|
||||||
@ -318,19 +318,19 @@ class Updates extends Controller
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($plugins as $name => $hash) {
|
foreach ($themes as $name => $hash) {
|
||||||
$updateSteps[] = [
|
$updateSteps[] = [
|
||||||
'code' => 'downloadPlugin',
|
'code' => 'downloadTheme',
|
||||||
'label' => Lang::get('system::lang.updates.plugin_downloading', compact('name')),
|
'label' => Lang::get('system::lang.updates.theme_downloading', compact('name')),
|
||||||
'name' => $name,
|
'name' => $name,
|
||||||
'hash' => $hash
|
'hash' => $hash
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($themes as $name => $hash) {
|
foreach ($plugins as $name => $hash) {
|
||||||
$updateSteps[] = [
|
$updateSteps[] = [
|
||||||
'code' => 'downloadTheme',
|
'code' => 'downloadPlugin',
|
||||||
'label' => Lang::get('system::lang.updates.theme_downloading', compact('name')),
|
'label' => Lang::get('system::lang.updates.plugin_downloading', compact('name')),
|
||||||
'name' => $name,
|
'name' => $name,
|
||||||
'hash' => $hash
|
'hash' => $hash
|
||||||
];
|
];
|
||||||
@ -348,19 +348,19 @@ class Updates extends Controller
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($plugins as $name => $hash) {
|
foreach ($themes as $name => $hash) {
|
||||||
$updateSteps[] = [
|
$updateSteps[] = [
|
||||||
'code' => 'extractPlugin',
|
'code' => 'extractTheme',
|
||||||
'label' => Lang::get('system::lang.updates.plugin_extracting', compact('name')),
|
'label' => Lang::get('system::lang.updates.theme_extracting', compact('name')),
|
||||||
'name' => $name,
|
'name' => $name,
|
||||||
'hash' => $hash
|
'hash' => $hash
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($themes as $name => $hash) {
|
foreach ($plugins as $name => $hash) {
|
||||||
$updateSteps[] = [
|
$updateSteps[] = [
|
||||||
'code' => 'extractTheme',
|
'code' => 'extractPlugin',
|
||||||
'label' => Lang::get('system::lang.updates.theme_extracting', compact('name')),
|
'label' => Lang::get('system::lang.updates.plugin_extracting', compact('name')),
|
||||||
'name' => $name,
|
'name' => $name,
|
||||||
'hash' => $hash
|
'hash' => $hash
|
||||||
];
|
];
|
||||||
@ -600,6 +600,15 @@ class Updates extends Controller
|
|||||||
$themes = [$name => $hash];
|
$themes = [$name => $hash];
|
||||||
$plugins = [];
|
$plugins = [];
|
||||||
|
|
||||||
|
foreach ((array) array_get($result, 'require') as $plugin) {
|
||||||
|
if (
|
||||||
|
($name = array_get($plugin, 'code')) &&
|
||||||
|
($hash = array_get($plugin, 'hash'))
|
||||||
|
) {
|
||||||
|
$plugins[$name] = $hash;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Update steps
|
* Update steps
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user