October CMS Routing - php

I'm trying to configure routes in my OctoberCMS app. I configure routes in Plugin.php file of my plugin.
At the moment my code:
public function boot()
{
Validator::extend('numeric_for_repeater', function($attribute, $value, $parameters) {
foreach ($value as $v)
{
$validator = Validator::make(
$v,
[
'stock_quantity' => 'sometimes|numeric',
'stock_votes_quantity' => 'sometimes|numeric',
'value' => 'sometimes|numeric',
],
$parameters
);
if ($validator->fails())
return false;
}
return true;
});
\Route::get('/oferty/{id}', function ($id = null) {
$theme = Theme::getActiveTheme();
$path = \Config::get('cms.themesPath', '/themes').'/'.$theme->getDirName();
$this->assetPath = $path;
$offer = new Offer();
return \View::make(self::MAMF_PAGE_DIR . 'oferta.htm', ['offer' => $offer->getOfferById($id)]);
});
}
but I got an error:
View [.var.www.plugins.mamf.mamf2017..........themes.mamf2017.pages.oferta.htm] not found. because by default October expects views files in plugin directory.
How can I render view outside of plugin dir, for ex in themes path like this app/themes/mamf2017/pages/oferta.htm

I guess self::MAMF_PAGE_DIR is full base path your application. for example like
/var/www/vhosts/octdev/themes/responsiv-flat/
In short \View::make need absolute path from root
now it will try to look file with configured extensions for october-cms its .htm. others are .blade and .htm.blade etc ..
so in your case (view)file name is 'oferta.htm' that .(dot) is translated to '/' path separator so just don't use it and just use 'oferta' so it will check all possible values in pages directory
oferta.htm
oferta.blade
oferta.htm.balde
this adding .htm is automatic thing so you just need to provide name of view then it will find and work automatically
\Route::get('/oferty/{id}', function ($id = null) {
$theme = \Cms\Classes\Theme::getActiveTheme();
$path = \Config::get('cms.themesPath', '/themes').'/'.$theme->getDirName();
$this->assetPath = $path;
$offer = new Offer();
return \View::make(base_path() . $path . '/pages/' . 'oferta', ['offer' => $offer->getOfferById($id)]);
});
this is tested and working fine hope this will help you.
if its not working please comment.

Related

Get current template filename in Twig Extension

I'm writing an extension for textblocks on my site. Therefore I made a twig extensions. As every textblock needs to be unique I included the template name in the filename of the textblock as well as a hook name. However I need to get the current template filename that called a twig extension.
It seems to be in the environment variable of twig, but is is not accessible.
My only workaround is to make the current template name a parameter of the function itself: {{ textblock_render('textblock_name', _self) }}, which seems a bit unnecessary.
So is there a way to get the current twig template filename, that called the extension?
class TextBlockExtension extends AbstractExtension
{
public function getFunctions()
{
return [
new TwigFunction('textblock_render', [$this, 'textblock'], ['is_safe' => ['html'], 'needs_environment' => true])
];
}
public function textblock(Environment $twig, string $hook, string $filename)
{
$loader = $twig->getLoader();
if (preg_match(TextblockController::REGEX_TEXTBLOCK, $hook) === 1) {
$path = '_partial/textblocks/' . md5('templates/' . $filename) . '-' . $hook . '.html.twig';
if ($loader->exists($path)) {
return $twig->render($path);
}
}
return false;
}
}

Laravel get uploaded image on CKEDITOR

when i use from ckeditor to upload image and attach that on post my upload image function in controller work fine without any problem, but when i want to return uploaded image to that, ckeditor can't get that, for example this is my code:
Controller:
public function uploadImageContent()
{
$this->validate(request(), [
'upload' => 'mimes:jpeg,jpg,gif,png'
]);
$file = request()->file('upload');
$filename = $file->getClientOriginalName();
$year = Carbon::now()->year;
$imagePath = "/uploads/post_images/{$year}/";
if (file_exists(public_path($imagePath) . $filename)) {
$filename = Carbon::now()->timestamp . '.' . $filename;
}
$file->move(public_path() . $imagePath, $filename);
$url = $imagePath . $filename;
return "<script>window.parent.CKEDITOR.tools.callFunction(1,'{$url}','')</script>";
}
this function work fine and i dont get any error on console or network
return "<script>window.parent.CKEDITOR.tools.callFunction(1,'{$url}','')</script>";
should be return path, but dont work.
view:
<script>
$(function () {
CKEDITOR.replace('description', {
height: '200px',
extraPlugins: 'forms',
filebrowserUploadUrl:'/dashboard/administrator/attachImage',
filebrowserImageUploadUrl:'/dashboard/administrator/attachImage'
});
});
</script>
route:
Route::group(['namespace' => 'Dashboard', 'prefix' => 'dashboard'], function () {
$this->group(['prefix' => 'administrator'], function () {
...
$this->post('/attachImage', 'ContentsController#attachImage');
...
});
ContentsController:
class ContentsController extends Controller
{
...
public function attachImage()
{
$this->uploadImageContent(request()->all());
}
}
Your code did not work for me. What I observed is, you are not embedding the CKEditorFuncNum (which server receives as POST variable) at the place of 1 as the first parameter to callFunction(). I replaced the 1 with $request->CKEditorFuncNum and then I used return statement instead of echo and it all works.
Here's your code:
echo "<script>window.parent.CKEDITOR.tools.callFunction(1,'{$url}','')</script>";
and
Here's my code:
return "<script>window.parent.CKEDITOR.tools.callFunction('{$request->CKEditorFuncNum}','{$url}','')</script>";
I'm on Laravel 5.8
Hope it helps others.
using echo instead of return resolve my problem:
echo "<script>window.parent.CKEDITOR.tools.callFunction(1,'{$url}','')</script>";
i have this issue on laravel 5.5

CakePHP 3 - call object from other helper

I'm actually working on a Helper for CakePHP3 that include BsHelper and then the BsFormHelper.
Actually everything looks good, no problem with Bootstrap formats.
I try now to create a ckEditor instance, but I meet some several problems.
If i try to call my ckEditor like this :
$this->BsForm->ckEditor('test')
I just have some problems because the function ckEditor is in my BsFormHelper, and load function is in BsHelper. So when i try to access private var to know if i had to load ckEditor i got that issue :
Error: Call to a member function load() on a non-object
File C:\wamp3\www\wac_lucien\BsHelpersCakePHP3\3.2\plugins\BsHelpers\src\View\Helper\BsFormHelper.php
So in fact I know where is the issue :
In BsFormHelper my fonction looks like :
public function ckEditor($fieldName, $options = array(), $ckEditorOptions = array()) {
$options['type'] = 'textarea';
$out = $this->input($fieldName, $options);
// If there is a point in the fieldName
if (strpos($fieldName, '.') !== false) {
$nameForReplace = Inflector::camelize(Inflector::slug($fieldName));
} else {
$nameForReplace = $this->_modelForm . Inflector::camelize($fieldName);
}
$this->Bs->load('ckeditor');
$this->Bs->loadJS('CKEDITOR.replace("' . $nameForReplace . '", ' . json_encode($ckEditorOptions) . ');', true);
return $out;
}
And in my BsHelper i got :
public function load($key) {
if (!$this->__extensions[$key]['loaded']) {
foreach ($this->__extensions[$key]['css'] as $css) {
$this->loadCSS($css);
}
foreach ($this->__extensions[$key]['js'] as $js) {
$this->loadJS($js);
}
$this->__extensions[$key]['loaded'] = true;
}
return $this->__extensions[$key]['loaded'];
}
Values are in declaration like this
public $__extensions = array(
'jasny' => array(
'css' => array(
'//cdnjs.cloudflare.com/ajax/libs/jasny-bootstrap/3.1.3/css/jasny-bootstrap.min.css'
),
'js' => array(
'//cdnjs.cloudflare.com/ajax/libs/jasny-bootstrap/3.1.3/js/jasny-bootstrap.min.js'
),
'loaded' => true
),
'ckeditor' => array(
'css' => array(),
'js' => array(
'//cdn.ckeditor.com/4.5.8/standard/ckeditor.js'
),
'loaded' => true
)
);
Can someone help me to find out ? It looks like load function called in BsFormHelper can't access privates vars from BsHelper ...
seems you are just trying to use a helper in another helper
The manual says
You may wish to use some functionality already existing in another
helper. To do so, you can specify helpers you wish to use with a
$helpers array, formatted just as you would in a controller:
So in your BsFormHelper just do
public $helpers = ['Bs'];
and you're done

In Laravel, how can I obtain a list of all files in a public folder?

I'd like to automatically generate a list of all images in my public folder, but I cannot seem to find any object that could help me do this.
The Storage class seems like a good candidate for the job, but it only allows me to search files within the storage folder, which is outside the public folder.
You could create another disk for Storage class. This would be the best solution for you in my opinion.
In config/filesystems.php in the disks array add your desired folder. The public folder in this case.
'disks' => [
'local' => [
'driver' => 'local',
'root' => storage_path().'/app',
],
'public' => [
'driver' => 'local',
'root' => public_path(),
],
's3' => '....'
Then you can use Storage class to work within your public folder in the following way:
$exists = Storage::disk('public')->exists('file.jpg');
The $exists variable will tell you if file.jpg exists inside the public folder because the Storage disk 'public' points to public folder of project.
You can use all the Storage methods from documentation, with your custom disk. Just add the disk('public') part.
Storage::disk('public')-> // any method you want from
http://laravel.com/docs/5.0/filesystem#basic-usage
Later Edit:
People complained that my answer is not giving the exact method to list the files, but my intention was never to drop a line of code that the op copy / paste into his project. I wanted to "teach" him, if I can use that word, how to use the laravel Storage, rather then just pasting some code.
Anyway, the actual methods for listing the files are:
$files = Storage::disk('public')->files($directory);
// Recursive...
$files = Storage::disk('public')->allFiles($directory);
And the configuration part and background are above, in my original answer.
Storage::disk('local')->files('optional_dir_name');
or just a certain type of file
array_filter(Storage::disk('local')->files(), function ($item) {
//only png's
return strpos($item, '.png');
});
Note that laravel disk has files() and allfiles(). allfiles is recursive.
Consider using glob. No need to overcomplicate barebones PHP with helper classes/methods in Laravel 5.
<?php
foreach (glob("/location/for/public/images/*.png") as $filename) {
echo "$filename size " . filesize($filename) . "\n";
}
?>
To list all files in directory use this
$dir_path = public_path() . '/dirname';
$dir = new DirectoryIterator($dir_path);
foreach ($dir as $fileinfo) {
if (!$fileinfo->isDot()) {
}
else {
}
}
You can use FilesystemReader::listContents
Storage::disk('public')->listContents();
Sample response...
[
[
"type" => "file",
"path" => ".gitignore",
"timestamp" => 1600098847,
"size" => 27,
"dirname" => "",
"basename" => ".gitignore",
"extension" => "gitignore",
"filename" => "",
],
[
"type" => "dir",
"path" => "avatars",
"timestamp" => 1600187489,
"dirname" => "",
"basename" => "avatars",
"filename" => "avatars",
]
]
User File Namespace for getting the public path. then use this code to get all the files from the selected directory
use File;
for example the public directory name is "media"
$path = public_path('media');
$filesInFolder = File::allFiles($path);
foreach($filesInFolder as $key => $path){
$files = pathinfo($path);
$allMedia[] = $files['basename'];
}
in laravel just use :
use Illuminate\Support\Facades\File;
$path = public_path();
$files = File::allFiles($path);
dd($files);
i hope it was useful !
To list all images in your public dir try this:
see here btw http://php.net/manual/en/class.splfileinfo.php
function getImageRelativePathsWfilenames(){
$result = [];
$dirs = File::directories(public_path());
foreach($dirs as $dir){
var_dump($dir); //actually string: /home/mylinuxiser/myproject/public"
$files = File::files($dir);
foreach($files as $f){
var_dump($f); //actually object SplFileInfo
//object(Symfony\Component\Finder\SplFileInfo)#628 (4) {
//["relativePath":"Symfony\Component\Finder\SplFileInfo":private]=>
//string(0) ""
//["relativePathname":"Symfony\Component\Finder\SplFileInfo":private]=>
//string(14) "text1_logo.png"
//["pathName":"SplFileInfo":private]=>
//string(82) "/home/mylinuxiser/myproject/public/img/text1_logo.png"
//["fileName":"SplFileInfo":private]=>
//string(14) "text1_logo.png"
//}
if(ends_with($f, ['.png', '.jpg', '.jpeg', '.gif'])){
$result[] = $f->getRelativePathname(); //prefix your public folder here if you want
}
}
}
return $result; //will be in this case ['img/text1_logo.png']
}
Please use the following code and get all the subdirectories of a particular folder in the public folder. When some click the folder it lists the files inside each folder.
Controller File
public function index() {
try {
$dirNames = array();
$this->folderPath = 'export'.DS.str_replace( '.', '_', $this->getCurrentShop->getCurrentShop()->shopify_domain ).DS.'exported_files';
$getAllDirs = File::directories( public_path( $this->folderPath ) );
foreach( $getAllDirs as $dir ) {
$dirNames[] = basename($dir);
}
return view('backups/listfolders', compact('dirNames'));
} catch ( Exception $ex ) {
Log::error( $ex->getMessage() );
}
}
public function getFiles( $directoryName ) {
try {
$filesArr = array();
$this->folderPath = 'export'.DS.str_replace( '.', '_', $this->getCurrentShop->getCurrentShop()->shopify_domain ).DS.'exported_files'. DS . $directoryName;
$folderPth = public_path( $this->folderPath );
$files = File::allFiles( $folderPth );
$replaceDocPath = str_replace( public_path(),'',$this->folderPath );
foreach( $files as $file ) {
$filesArr[] = array( 'fileName' => $file->getRelativePathname(), 'fileUrl' => url($replaceDocPath.DS.$file->getRelativePathname()) );
}
return view('backups/listfiles', compact('filesArr'));
} catch (Exception $ex) {
Log::error( $ex->getMessage() );
}
}
Route ( Web.php )
Route::resource('displaybackups', 'Displaybackups\BackupController')->only([ 'index', 'show']);
Route::get('get-files/{directoryName}', 'Displaybackups\BackupController#getFiles');
View files - List Folders
#foreach( $dirNames as $dirName)
<div class="col-lg-3 col-md-3 col-sm-4 align-center">
<a href="get-files/{{$dirName}}" class="btn btn-light folder-wrap" role="button">
<span class="glyphicon glyphicon-folder-open folderIcons"></span>
{{ $dirName }}
</a>
</div>
#endforeach
View - List Files
#foreach( $filesArr as $fileArr)
<div class="col-lg-2 col-md-3 col-sm-4">
<a href="{{ $fileArr['fileUrl'] }}" class="waves-effect waves-light btn green folder-wrap">
<span class="glyphicon glyphicon-file folderIcons"></span>
<span class="file-name">{{ $fileArr['fileName'] }}</span>
</a>
</div>
#endforeach
You can get all the files doing:
use Illuminate\Support\Facades\Storage;
..
$files = Storage::disk('local')->allFiles('public');
Laravel On-Demand Disks
https://laravel.com/docs/9.x/filesystem#on-demand-disks
use Illuminate\Support\Facades\Storage;
$disk = Storage::build([
'driver' => 'local',
'root' => '/path/to/root',
]);
$disk->put('image.jpg', $content);
Additionaly, you can use files or allFiles methods to get files from another directories.
Both returns array, but files allow recursive way.
>>> man $disk->allFiles
class Illuminate\Filesystem\FilesystemAdapter implements Illuminate\Contracts\Filesystem\Cloud, Illuminate\Contracts\Filesystem\Filesystem
public function allFiles($directory = null)
Description:
Get all of the files from the given directory (recursive).
Param:
string|null $directory
Return:
array
>>> man $disk->files
class Illuminate\Filesystem\FilesystemAdapter implements Illuminate\Contracts\Filesystem\Cloud, Illuminate\Contracts\Filesystem\Filesystem
public function files($directory = null, $recursive = false)
Description:
Get an array of all files in a directory.
Param:
string|null $directory
bool $recursive
Return:
array
>>>

Zend Framework - Custom defined routes overridden when adding Zend_Rest_Route

I'm creating an application that exposes a RESTful API in a module called api. For the other modules I created a little class that returns a Zend_Controller_Router_Rewrite object with custom defined routes:
$router = new Zend_Controller_Router_Rewrite();
foreach ($this->_modules as $module) {
if ($module === 'api') continue;
foreach ($this->_getConfigFiles($module) as $filename) {
$config = new Zend_Config_Ini($filename, 'routes');
$router->addConfig($config, 'routes');
}
}
return $router;
For the default module I have the following route:
[routes]
routes.default_index_index.type = Zend_Controller_Router_Route
routes.default_index_index.route = /
routes.default_index_index.defaults.module = default
routes.default_index_index.defaults.controller = index
routes.default_index_index.defaults.action = index
Now, in my Bootstrap file file I have the following:
$router = Shark_Module_Loader::getInstance()->getRouter();
$frontController->setRouter($router);
$frontController->getRouter()->removeDefaultRoutes();
$apiRoute = new Zend_Rest_Route($frontController, array(), array('api'));
$router->addRoute('rest', $apiRoute);
If I skip adding the rest route everything works fine for the default module, of course. But when I add the RESTful route the routes defined in the router are overridden(?), so the current route in the index action of the index controller of the default module ($this->getFrontController()->getRouter()->getCurrentRoute();) is an instance of Zend_Rest_Route. Thus, when trying to access a custom route defined in on of the route config files, lets say:
...
routes.default_pages_view.type = Zend_Controller_Router_Route
routes.default_pages_view.route = /view/:page
routes.default_pages_view.defaults.module = default
routes.default_pages_view.defaults.controller = pages
routes.default_pages_view.defaults.action = view
...
I get a 404 error saying that the request action (get) is not present.
I already went through the docs and didn't see any hint that suggests this behavior.
Any help and guidance will be appreciated.
There is no way to do this out of the box. (Check out this question)
You need to extend the Zend_Controller_Router_Route class. I've done it like this:
class Mauro_Controller_Router_Route_Method extends Zend_Controller_Router_Route {
protected $_method;
public function __construct($route, $defaults = array(), $reqs = array(), Zend_Translate $translator = null, $locale = null) {
list($this->_method, $route) = explode(' ', $route, 2);
parent::__construct($route, $defaults, $reqs, $translator, $locale);
}
public function match($path, $partial = false) {
$requestMethod = $this->getRequest()->getMethod();
$requestMethod = $this->getRequest()->getParam('method')
? strtoupper($this->getRequest()->getParam('method'))
: $requestMethod;
return $requestMethod == strtoupper($this->_method)
? parent::match($path, $partial)
: false;
}
protected function getRequest() {
return Zend_Controller_Front::getInstance()->getRequest();
}
}
You can then use it like this:
$router->addRoute( new Mauro_Controller_Router_Route_Method( 'GET /view/:page', array( 'controller' => 'pages', 'action' => 'view' ), array( 'page' => '/d+', ) ) );

Categories