CakePHP Media Plugin - Upload Folder - cakephp

I am using the Media Plugin (http://www.ohloh.net/p/cakephp-media).
I wanna define custom folder for all the uplaods. i am a little confused where it has to be done.
This is the folder structure i want to achieve
webroot/media/image/original (for the original file storage)
webroot/media/image/large (for the large image filter)
webroot/media/image/medium (for the medium image filter)
webroot/media/image/small (for the small image filter)
also i want to use a random name that i want to generate using the following sript.
//UUID generator
function _imgName() {
return time() . substr(md5(microtime()), 0, 12);
}

Firstly, having used this plugin, I would recommend considering the default directory structure to keep your app simpler. You don't want to edit the plugin directly as it will make upgrading more painful...
# /app/webroot/media/transfer/img/slug.ext (for the original file storage)
# /app/webroot/media/filter/l/img/slug.ext (for the large image filter)
# /app/webroot/media/filter/m/img/slug.ext (for the medium image filter)
# /app/webroot/media/filter/s/img/slug.ext (for the small image filter)
However, the Media plugin configuration file is located at /app/plugins/media/config/core.php and contains some constants that you can override application-wide by defining them in /app/config/bootstrap.php first. To achieve a format somewhat similar to what you want, you could define the following variables:
define('MEDIA_TRANSFER', WWW_ROOT . 'media' . DS . 'original' . DS);
define('MEDIA_FILTER', WWW_ROOT . 'media' . DS);
define('MEDIA_TRANSFER_URL', 'media/original/');
define('MEDIA_FILTER_URL', 'media/');
# /app/webroot/media/original/img/slug.ext (for the original file storage)
# /app/webroot/media/l/img/slug.ext (for the large image filter)
# /app/webroot/media/m/img/slug.ext (for the medium image filter)
# /app/webroot/media/s/img/slug.ext (for the small image filter)
(Note: you can also set the above paths on a per-model basis by passing the correct configuration options when adding the behavior to your models.)
You can also redefine the names of the image filters being used to get a step closer to your goal. You need to do this in /app/config/bootstrap.php again, but after you have loaded the Media plugin configuration:
require APP . 'plugins' . DS . 'media' . DS . 'config' . DS . 'core.php';
Configure::write('Media.filter.image', array(
'small' => array('convert' => 'image/png', 'zoomCrop' => array(100, 100)),
'medium' => array('convert' => 'image/png', 'fitCrop' => array(300, 300)),
'large' => array('convert' => 'image/png', 'fit' => array(600, 440)),
));
# /app/webroot/media/original/img/slug.ext (for the original file storage)
# /app/webroot/media/large/img/slug.ext (for the large image filter)
# /app/webroot/media/medium/img/slug.ext (for the medium image filter)
# /app/webroot/media/small/img/slug.ext (for the small image filter)
If you read the documentation for the Media.TransferBehavior::transferTo() method, you will see you can customize the latter part of the path (ie. img/slug.ext) by reimplementing this method in your model (eg. MyModel::transferTo()). Something like this would get you even closer:
class MyModel extends AppModel {
public function transferTo($via, $from) {
extract($from);
$mime = Mime_Type::guessName($mimeType ? $mimeType : $file);
$name = $this->_imgName();
$path = $mime . DS . $name
$path .= !empty($extension) ? '.' . strtolower($extension) : null;
return $path;
}
}
# /app/webroot/media/original/image/129916996632c787226a0b.ext (for the original file storage)
# /app/webroot/media/large/image/129916998392a3570a1828.ext (for the large image filter)
# /app/webroot/media/medium/image/12991699891c7625bebedb.ext (for the medium image filter)
# /app/webroot/media/small/image/12991699938ab22d80cfc6.ext (for the small image filter)
While not exactly what you were looking for (/large/image/ vs /image/large/), this is about as far as you can go without reimplementing larger portions of the plugin. This is because the path is treated as two parts (eg. /media/large/ and image/129916998392a3570a1828.ext) that get appended together later. You can see the append operation happening in the Media.TransferBehavior::_prepare() method and in the Media.GeneratorBehavior::make() method. You would need to either extend the plugin and duplicate those methods (with alterations) in your application code, or hack those two lines directly to get the desired output!

Related

File system path for images

I'm writing a custom helper that extends HtmlHelper and overriding the \HtmlHelper::image() method to calculate the image dimensions and add them as HTML attributes. What I have so far works fine for regular pictures:
public function image($path, $options = array()) {
if (!array_key_exists('width', $options) && !array_key_exists('height', $options)) {
$stamp = Configure::read('Asset.timestamp');
Configure::write('Asset.timestamp', false);
$path = $this->assetUrl($path, $options + array('pathPrefix' => Configure::read('App.imageBaseUrl')));
list($width, $height) = #getimagesize(rtrim(WWW_ROOT, '\\/') . $path);
if (!is_null($width)) {
$options['width'] = $width;
}
if (!is_null($height)) {
$options['height'] = $height;
}
Configure::write('Asset.timestamp', $stamp);
}
return parent::image($path, $options);
}
… but has these flaws:
Pictures from plug-ins can't be located on disk (and they should), e.g.:
echo $this->Html->image('/debug_kit/img/cake.icon.png', array('alt' => 'CakePHP'));
… produces this file system path:
…\src\webroot/debug_kit/img/cake.icon.png
… thus getimagesize() fails because actual location is:
…\src\Plugin\DebugKit\webroot\img\cake.icon.png"
External pictures (which should be ignored) go through the full process:
echo $this->Html->image('http://placekitten.com/200/300');
…\src\webroothttp://placekitten.com/200/300
I've been looking for a builtin method to convert a CakePHP picture URL (in any format accepted by \HtmlHelper::image() into a file system path (o something like null when doesn't apply) but I couldn't find any. Native features that need a disk path, such as \Helper::assetTimestamp() are wrapped in tons of non-reusable code.
Is there an elegant solution?
I'd say that there are pretty much only 3 options:
Submit a patch to add asset filesystem path retrieval functionality to the core.
Copy a lot of code from the helper (assetUrl(), webroot(), and assetTimestamp()).
Use web requests for local URLs (ideally combined with caching).
Try using DS rather than using \ or /, they sometime can cause problems with the OS.
DS is directory separator provided by cakephp Short for PHP’s DIRECTORY_SEPARATOR, which is / on Linux and \ on Windows.
Check the doc

Cakephp 2.6.1, PHPExcel "Unable to load PDF Rendering library"

On the same project i'm using phpExcel to generate excel files just fine.
PHPExcel files location:
C:\wamp\www\circulo\app\Vendor\PHPExcel\ (this folder contains PHPExcel.php along with PHPExcel files folder)
Also on the same project, i'm using dompdf alone to generate pdf file just fine (not via PHPExcel). I've just liked a lot how PHPExcel allows excel file construction so i'd like to create pdfs via PHPExcel as well.
dompdf files location:
C:\wamp\www\circulo\app\Vendor\dompdf\
The path seems correct via debugger => C:\wamp\www\circulo\app\Vendor\dompdf\dompdf.php
This is my code to get a pdf file:
I get error:
[PHPExcel_Writer_Exception] Unable to load PDF Rendering library
error_reporting(E_ALL);
ini_set('display_errors', TRUE);
ini_set('display_startup_errors', TRUE);
define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');
require_once APP . DS . 'Vendor' . DS . 'PHPExcel' . DS . 'PHPExcel.php';
$rendererName = PHPExcel_Settings::PDF_RENDERER_MPDF;
$rendererLibrary = 'dompdf.php';
$rendererLibraryPath = APP . 'Vendor' . DS . 'dompdf' . DS .$rendererLibrary;
Debugger::log($rendererLibraryPath);
if (!PHPExcel_Settings::setPdfRenderer( $rendererName, $rendererLibraryPath )) { die( 'Please set the $rendererName and $rendererLibraryPath values' . PHP_EOL . ' as appropriate for your directory structure' . $rendererLibraryPath ); }
$objPHPExcel = new PHPExcel;
$objWriter = new PHPExcel_Writer_PDF($objPHPExcel);
//$objWriter->save("emptyPdfJustYet.pdf");
Tried their demo 21pdf.php to same results.
Can you help? Thanks a lot!!
When I print the error to log, I realize it is trying to load the dompdf_config.inc.php from an invalid location. See below.
C:\wamp\www\myapp\app\Vendor\dompdf\dompdf.php/dompdf_config.inc.php\n
Rather than altering the class files of PHPExcel, it's wise to change the configuration in your view. Ignoring the $rendererLibrary completely in the $rendererLibraryPath fixed my issue. I think the PHPExcel know how to pick dompdf.php file. Try below code let us know if it doesn't work.
And you are providing wrong render constant too, changed PDF_RENDERER_MPDF to PDF_RENDERER_DOMPDF.
$rendererName = PHPExcel_Settings::PDF_RENDERER_DOMPDF;
$rendererLibrary = 'dompdf.php';
$rendererLibraryPath = APP . 'Vendor' . DS . 'dompdf';
And for create writer object, I tried
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'PDF');

How to import vendor files in CakePHP 3x

I'm working with CakePHP 3(beta 2) version recently launched. I need to integrate Facebook Login using PHP SDKs and I'm not clear with importing vendor files in this version.
In CakePHP 2x, I had used
App::import('Vendor', 'Facebook', array('file' => 'Facebook' . DS . 'src'. DS. 'facebook.php'));
So I need to reproduce the same in CakePHP 3x(I'm not using composer).
Any reference for this?
Well you will have to load it yourself if composer is not an option. You can always use the very basic require method and create a new instance of the vendor class yourself. Reference: http://book.cakephp.org/3.0/en/core-libraries/app.html#loading-vendor-files
Use:
//The following line should do the same like App::import() in the older version of cakePHP
require_once(ROOT . 'vendor' . DS . 'Facebook' . DS . 'src' . DS . 'facebook.php');
$facebookApi = new facebook();
In cakephp3 , to add a new vendor library you can follow below steps :
Place library folder under your_project/vendor/
include library file using require_once(ROOT . DS . 'vendor' . DS . "my_library_folder" . DS . "my_library_base_class.php")
,this includes the library code file in our code.
Include class name in top of Controller like :
namespace App\Controller;
use MyLibraryBaseClass;
,
this imports the library code file in our namespace to be used.
create object of loaded class as
$my_obj= new MyLibraryBaseClass();
the answer provided by Ayman B. does not look like doing the job as expected in the question after i tried it myself , for the following reasons :
the vendor folder in cakephp3 is not located in src folder under APP namespace , it is moved to the ROOT folder , by doing you will not be able to load your Facebook class as expected , try it yourself and you will see the result ...
By loading a vendor file this is does not automatically load the class name itself , if your vendor lib does not follows the follwing rule as PSR-0 rule :
\VENDOR\PACKAGE\TEST.CLASS.PHP and inside the test.class.php there is not a class definition that must be called or imported in your script with a defined namespace keyword in the begining of this script as follows : namespace
then the code above will not work
To correct the answer you have to do some several steps as follows :
1 - Define in bootstrap.php a new cakephp constant like so :
define('VENDOR',ROOT . DS . 'vendor' .DS); as VENDOR constante is removed in cakephp 3.x you can define it yourself
2 - After that , you have to specify the vendor name , the package name and the class name in a vendor constante like :
define('_',; and then you can do $facebookApi = new \\();
this is will work for you as expected in the question
If you have issues try to get back to me , i will show you an example of use as described here ...
I also had the same problem with CakePHP 3.0.
Do the installation as instructed using Composer.
Then You have to properly load the plugin in your controller with the use statement. Like this:
use Ghunti\HighchartsPHP\Highchart;
If you're using the plugin in most of the pages, instead of loading in each Controller, you can add the same line in your bootstrap.php file, right below the other use statements.
That will solve the problem of using the plugin.
As of CakePhp 3.x, the recommended code standard is to use require_once without the brackets"()".
require_once(ROOT.'Folder'.DIRECTORY_SEPARATOR.'requiredfile.ph');
becomes
require_once ROOT.'Folder'.DIRECTORY_SEPARATOR.'requiredfile.ph';
https://book.cakephp.org/3.0/en/contributing/cakephp-coding-conventions.html
Hope that helps someone in the future.

require command issue in CakePHP

I have a library in my project.When I want to use this with this code:
require('../Plugin/Utils/DateTimeUtil.php');
it says no such file exists. my cakephp 1s 2.3 what should I do?
The Routing in cakephp is different from pure php.I had something like this.At first you should find the path Plugin folder with this code
$pluginPath = App::path('Plugin');
Then It returns an array which contains the plugin folder's path in 0 index.So you should the returned value like blow:
require($pluginPath[0] . 'Utils' . DS . 'DateTimeUtil.php');
You can use slash instead of DS. DS is DIRECTORY_SEPRATOR.

drupal 7 file field formatter on custom node for javascript (to set up jQuizMe)

I have set up a module with custom node type (I called jquizme, after the javascript jQuizMe that I really like using). I set up two fields for the javascript files I need to supply to make it work (after the general jQuizMe-2.2.js file you need to add another two javascript files - one for settings and one for the quiz content).
Drupal saves the files as myjavascriptfile.js.txt - I tested them and they still work to make the jQuizMe interface - ok. the problem is, I want to add these files on the node page... the files will be different for each node. how can I access the files for the drupal_add_js() function so they will load the files for the node in question?
I tried setting up custom field formatters, but I don't know how to access the uri for the files of a given node automatically to put in the drupal_add_js() function (I can add a static file and it loads fine ... I did this with hook_node_view ( jquizme_node_view ).
So I just need a way to access the info for the files... how are they linked to each node? I can't find the connection.
As you probably noticed, I am a module writing newbie, and I probably won't understand much related to object oriented programming sorry, haven;t progressed to that level yet), but I am open to any answer. I am sure I left out important info, but this it already getting too long.
I also set up a special page earlier on to just see if I could get jQuizMe to work in Drupal so that is still in the code.
I have tried many answers (last six hours or so... too much to say here), the latest of which is using tokens, but that is not working. Here is what I have so far:
function jquizme_node_view($node, $view_mode, $langcode) {
switch ($node->type) {
case 'jquizme':
$items = field_get_items('node', $node, 'field_myfield', $node->language);
drupal_add_css(drupal_get_path('module', 'jquizme') . '/jQuizMe.css', >array('scope' => 'header'));
drupal_add_js(drupal_get_path('module', 'jquizme') . '/alert.js');
drupal_add_js(drupal_get_path('module', 'jquizme') . '/jQuizMe-2.2.js', >array('scope' => 'header'));
//drupal_add_js($tokens['node']['jquizme_js1_field'], array('scope' => >'header'));
//drupal_add_js($tokens['node']['jquizme_js2'], array('scope' => 'header'));
break;
}
}
Thanks in advance!
Can you try this?
// Let me assume that the field names of your two file fields
// are jquizme_js1_field and jquizme_js2_field for convenience..
function jquizme_node_view($node, $view_mode, $language) {
$items = field_get_items('node', $node, 'jquizme_js1_field');
_jquizme_add_js_from_filefield($items);
$items = field_get_items('node', $node, 'jquizme_js2_field');
_jquizme_add_js_from_filefield($items);
}
// Given the values of a filefield attached to some entity,
// adds them as JS files to the page.
function _jquizme_add_js_from_filefield($items = array()) {
foreach ($items as $item) {
$fid = &$item['fid'];
$file = file_load($fid);
if (!$file) {
continue; // Maybe the file got deleted..
}
$wrapper = file_stream_wrapper_get_instance_by_uri($file->uri);
$path = $wrapper->realpath();
// Ensure that the path exists and that it is a Javascript file..
if (file_exists($path) && preg_match('\.js$', $path)) {
drupal_add_js($path, array('type' => 'file'));
}
}
}

Resources