I'm trying to import Assetic (https://github.com/kriswallsmith/assetic) classes.
Managed to do the ugly :
App::import('Vendor', 'LessphpFilter', array('file' => 'assetic' . DS . 'src' . DS . 'Assetic' . DS . 'Filter' . DS . 'LessphpFilter.php'));
But it crashes on a sub-required file.
Any idea how to do achieve this in a clean way?
I had similar issues a couple of weeks ago and haven't found a really clean/satisfying way to do this. But I managed to solve problems with sub-required files by adding paths to the include path before the import. Like so:
$pathExtra = APP.'Vendor'.DS.PATH_SEPARATOR.APP.'Vendor'.DS.'pear'.DS;
$path = ini_get('include_path');
$path = $pathExtra . PATH_SEPARATOR . $path;
ini_set('include_path', $path);
App::import('Vendor', 'consumer', array('file' => 'Auth'.DS.'OpenID'.DS.'Consumer.php'));
Related
I want to create vendor package in cakephp 3. It should depend on another package, that has both php files and some static assets: like js, css, img etc. Setting up php files autoloading I am able to handle. However to load static files from another vendor, e.g.
echo $this->Html->css('AnotherPackage.styles');
cake expects that they should be inside vendor's webroot directory, which they are not
# another package's files
/vendor/author/another-package/php
/vendor/author/another-package/css_files
/vendor/author/another-package/js_files
/vendor/author/another-package/images
Only similar issue I found is copying files to webroot , which is something I do not want to do.
How can I tell cake to load the vendor's files from their exact folders instead of webroot ? Or in what better way this problem can be solved, without being have to copy something. I am using composer.
Thanks
Are you doing this on a Linux box? If so, you could just create a symbolic link in order to have the webroot directory point right back at the root directory of the package.
Are you using composer?
Does the project you're working on depend on the vendor's package within your composer.json file?
If so, you could create a Controller (something like ExternalAssets) in your project that can read those vendors files, and pass them through to the Response object.
<?php
/**
* ExternalAssetsController
*/
namespace App\Controller;
use App\Controller\Controller\AppController;
use Cake\Core\App;
use Cake\Http\Exception\BadRequestException;
use Cake\Http\Exception\ForbiddenException;
use Cake\Routing\Router;
/**
* ExternalAssets Controller
*
* Serves up external assets that aren't in the webroot folder.
*/
class ExternalAssetsController extends AppController
{
/**
* Initialize method.
*
* #return void
*/
public function initialize()
{
parent::initialize();
$this->loadComponent('RequestHandler');
// see https://book.cakephp.org/3.0/en/development/routing.html#routing-file-extensions
// or whatever extensions you need.
Router::extensions(['css', 'js', 'png', 'jpg']);
// if you're using the auth component in a restricted way.
$authAllowedActions = ['asset'];
$this->Auth->allow($authAllowedActions);
}
/**
* Delivers an asset.
*
* #param string|null $folder The Folder's name.
* #param string|null $file The File's name.
* #return \Cake\Http\Response
* #throws \Cake\Http\Exception\BadRequestException When $folder or $file isn't set.
* #throws \Cake\Http\Exception\ForbiddenException When we can't read the file.
*/
public function asset($folder = null, $file = null)
{
if (!$folder) {
throw new BadRequestException(__('Folder was not defined'));
}
if (!$file) {
throw new BadRequestException(__('File was not defined'));
}
$folder = str_replace('..', '', $folder);
$file = str_replace('..', '', $file);
$basepath = realpath(ROOT . DS . 'vendor' . DS . 'author' . DS . 'another-package');
$path = realpath(ROOT . DS . 'vendor' . DS . 'author' . DS . 'another-package' . DS . $folder . DS . $file . '.' . $this->getRequest()->getParam('_ext'));
if (strpos($path, $basepath) === false) {
throw new ForbiddenException(__('Path out of bounds, possible hack attempt.'));
}
if (!is_readable($path)) {
throw new ForbiddenException(__('Unable to read the file.'));
}
$this->setResponse($this->getResponse()->withFile($path, [
'name' => $file . '.' . $this->getRequest()->getParam('_ext'),
'download' => false
]));
return $this->getResponse();
}
}
Then use Router::url() to create the compiled path to your controller.
Something like:
<link rel="stylesheet" href="<?=Router::url([
'prefix' => false,
'plugin' => false, // unless the controller in in a plugin
'controller' => 'ExternalAssets'
'action' => 'asset'
0 => 'css_files',
1 => 'css_file_name',
'_ext' => 'css'
]) ?>">
I have been at this for a couple days now. Seems like the simplest thing in the world but for the life of me I cannot get this to work.
I am trying to use this class in my Controller:
https://github.com/neitanod/forceutf8
The class is named Encoding.php and it has a namespace ForceUTF8.
I've tried all of the following:
App::uses('Encoding','Vendor'); //(copying Encoding.php directly in the Vendor dir)
App::uses('Encoding','Vendor/ForceUTF8'); //(copying Encoding.php in ForceUTF8 subdir)
App::uses('Encoding’,’Lib'); //(copying Encoding.php directly in the Lib dir)
App::uses('Encoding’,’Lib/ForceUTF8'); //(copying Encoding.php in ForceUTF8 subdir)
require_once(APP . 'Vendor' . DS . 'Encoding.php'); //(use plain old php require_once to load class from Vendor dir)
No matter what I do I get the same error: Class 'Encoding' not found.
I find the CakePHP documentation to be very confusing on this subject. On the one hand it says not to use App::uses for non-CakePHP classes because the classes might not follow CakePHP standards. Fair enough. So instead they say to use App::import. But then there are tons of posts saying that App::import is nothing more than a wrapper for require_once.
So after not being able to get App::uses or App::import to work, I tried require_once. Same error. Then I found a post here on so saying even when using require_once, you still have to 'initialize' the class in order to CakePHP to be able to see/use it. And how is that done? App::uses. So I'm back where I started.
Something tells me the namespace is causing the problem. When I use require_once the class is found (I'm pretty sure) because, for example, if I change
require_once(APP . 'Vendor' . DS . 'Encoding.php');
to
require_once(APP . 'Vendor' . DS . 'blabla.php');
it gives me an error, file not found.
But even though require_once seems to find it, CakePHP still says class not found.
How can I load a namespaced vendor file?
In Cakephp 2.x, follow following steps
at top of class file add
use \Dropbox as dbx;
[Dropbox is vendor directory in my case]
use \Dropbox as dbx;
App::build(array('Vendor/Dropbox' => array('%s' . 'Dropbox' . DS)), App::REGISTER);
// Autoload the classes in the 'vendors'
spl_autoload_register(function ($class) {
foreach (App::path('Vendor') as $base) {
$path = $base . str_replace('\\', DS, $class) . '.php';
if (file_exists($path)) {
include $path;
return;
}
}
});
Now call your class method.
Cake2.x does not support namespaces so you need write your own loader
spl_autoload_register(function ($class) {
foreach (App::path('Vendor') as $base) {
$path = $base . str_replace('\\', DS, $class) . '.php';
if (file_exists($path)) {
include $path;
return;
}
}
});
more info here:
http://www.dereuromark.de/2012/08/06/namespaces-in-vendor-files-and-cake2-x/
Base on this article:
http://www.dereuromark.de/2012/08/06/namespaces-in-vendor-files-and-cake2-x/comment-page-1
I'm using the paypal sdk. And this is my code.
In bootstrap.php:
// Add 'vendors' as sub-package of 'Vendor' to the application
App::build(array('Vendor/vendors' => array('%s' . 'vendors' . DS)), App::REGISTER);
// Autoload the classes in the 'vendors'
spl_autoload_register(function ($class) {
foreach (App::path('Vendor/vendors') as $base) {
$path = $base . str_replace('\\', DS, $class) . '.php';
if (file_exists($path)) {
include $path;
return;
}
}
});
In the PaypalComponent:
use PayPal\Rest\ApiContext;
use PayPal\Auth\OAuthTokenCredential;
Use those classes in function:
$this->apiContext = new ApiContext(
new OAuthTokenCredential()
);
I am in a problem with CakePDF. I am using CakePHP 2.3.6. I setup everything alright, bootstrap & core files are ok.
Now, I want to generate many pdf files and download them. Downloading is ok, but when I download the files, I see that the generated pdf files say that Undefined $data, where I send $data to the view file.
Here is my Controller code:
App::uses('CakePdf', 'CakePdf.pdf');
// ...
public function createPdf($id) {
$data = $this->DBTable->find('all', array(
'conditions' => array(
'DBTable.id' => $id
)
));
$CakePdf = new CakePdf();
$path = APP . DS . 'pdf' . DS;
foreach($data as $key => $var) {
$CakePdf->template('create', 'default');
$this->set('var', $var);
$this->pdfConfig = array(
'orientation' => 'portrait',
'filename' => $var['id'] . ".pdf"
);
$CakePdf->write($path . $var['id'] . ".pdf");
}
}
Here, I am downloading the files some other way, not related to this problem, because downloading is ok. When I run this, all files are downloaded, and when I see the files, they say "Udefined var", looks like they didn't receive and variable called "$var".
I put the view file & the layout exactly where ceeram said.
What should I do now ? Please help me.
At last I got a solution to this. In the Controller function :
$data=$this->ModelName->find('all');
$CakePdf=new CakePdf();
$CakePdf->template('view_file','default');
$this->pdfConfig=array('orientation'=>'portrait','filename'=>$data['name']);
$CakePdf->viewVars(array('data'=>$data));
$CakePdf->write($path.$data['name'].".pdf");
Here, we have to store view_file.ctp in View/Pdf/, and default in View/Layouts/pdf/, where view_file.ctp is the view file which we want to convert in pdf, and default is the layout for this specific view file.
Here, viewVars() function passes the data to the view file, just like :
$this->set->('data',$data);
Let me know if anything is not clear here.
Thanks.
I want to generate web URLs to files uploaded by users, and serialize them.
In the controller I can do something like:
$myURL = Router::url('/', TRUE) . 'files' . DS . $relationName . DS . 'attachment' . DS . $attachmentData['dir'] . $attachmentData['attachment'];
But if the filename has spaces, it will not be escaped.
I know I can use the html helper in the view, but this means I will not be able to use the serialize magic from the controller.Also I don't want to break cake by using the HTML helper in the controller, or model.
I's there a way to create web URLs (http://example.c.../someimage.jpg) to files in webroot from the controller?
I tried the following tests variables passed in serialize:
$test = 'http://my.url.com/test.jpg';
$test1 = 'http://my.url.com/test file.jpg';
$test2 = urlencode('http://my.url.com/test file.jpg');
And the result is:
"test": "http:\/\/my.url.com\/test.jpg",
"test1": "http:\/\/my.url.com\/test file.jpg",
"test2": "http%3A%2F%2Fmy.url.com%2Ftest+file.jpg"
So I don't see any problem, urls are properly JSON encoded in test and test1 and test2 is already urlencoded from PHP so it is passed as is.
How can i retrieve absolute path of view and layout file in cakephp action.
I cant find useful method or property in
// in action
var_dump($this);
Thank
desire out put is
/home/sweb/www/cakeapp/app/View/Layout/mylayout.ctp
/home/sweb/www/cakeapp/app/View/Mycntl/myaction.ctp
I would use this to create a full path.
APP . 'View' . DS . 'Layout' . DS . $this->layout
Which will output something like this for you,
string '/Users/david/Sites/ExampleSite/app/View/Layout/default' (length=56)
In order to get the view, I'd use
APP . 'View' . DS . $this->modelClass . DS . $this->view