I'm trying to use FirePHP with Zend Framework 2, but there seems to be something missing. Here's the basic code I'm trying to run:
$writer = new Zend\Log\Writer\FirePhp();
$logger = new Zend\Log\Logger();
$logger->addWriter($writer);
$logger->info('FirePHP logging enabled');
The error I get is "FirePHP Class not found". I was initially puzzled because I do have a FirePhp class in my Zend/Log/Writer folder. But then I saw that the class constructor requires a FirePhp\FirePhpInterface object. So I checked the Zend/Log/Writer/FirePhp folder and there's a FirePhpBridge class in there that implements FirePhpInterface, but it also requires a FirePHP instance in the constructor. I don't have any FirePHP.php file in my Zend/Log/Writer/FirePhp folder. Am I supposed to get this from somewhere else?
Update
I now have managed to get FirePHP working, but I'm trying to figure out how to do it in a clean way so this works. The only way I've gotten it to work is putting it in the root directory of my project and doing the following:
include_once('FirePHP.php');
$writer = new Zend\Log\Writer\FirePhp(new Zend\Log\Writer\FirePhp\FirePhpBridge(FirePHP::getInstance(true)));
$logger = new Zend\Log\Logger();
$logger->addWriter($writer);
$logger->info('FirePHP logging enabled');
I assume that normally I should be able to create a writer like so:
$writer = new Zend\Log\Writer\FirePhp();
However, where this goes wrong I believe is in the getFirePhp() function of the Zend\Log\Writer\FirePhp class. The class does this:
if (!$this->firephp instanceof FirePhp\FirePhpInterface
&& !class_exists('FirePHP')
) {
// No FirePHP instance, and no way to create one
throw new Exception\RuntimeException('FirePHP Class not found');
}
// Remember: class names in strings are absolute; thus the class_exists
// here references the canonical name for the FirePHP class
if (!$this->firephp instanceof FirePhp\FirePhpInterface
&& class_exists('FirePHP')
) {
// FirePHPService is an alias for FirePHP; otherwise the class
// names would clash in this file on this line.
$this->setFirePhp(new FirePhp\FirePhpBridge(new FirePHPService()));
}
This is where I get lost as to how I'm supposed to set things up so that this class_exists('FirePHP') call finds the right class and new FirePHPService() also works properly.
First you should add this code to Module.php of your module
return array(
//...
'Zend\Loader\ClassMapAutoloader' => array(
__DIR__ . '/autoload_classmap.php',
),
);
and here content of autoload_classmap.php
<?php
return array(
'FirePHP' => realpath(APPLICATION_PATH . '/vendor/FirePHP').'/FirePHP.php',
);
FirePHP.php(renamed from FirePHP.class.php) downloaded from official site.
then you can write below code in any place of your module and it will work
use Zend\Log\Writer\FirePhp;
use Zend\Log\Logger;
$writer = new FirePhp();
$logger = new Logger();
$logger->addWriter($writer);
$logger->info("hi");
Am I supposed to get this from somewhere else?
Yes, you need to get FirePHP into your project and autoloading.
If you're using composer (and I recommend that you do), just add:
"firephp/firephp-core" : "dev-master"
(or similar) in your composer.json and update. If you're not using composer, you should grab the firephp libs, and let your autoloader know about them.
Related
(Symfony3)
I'm toying with the idea of setting up some simple cron tasks to generate security reports for our project managers so that they can schedule upgrade time for developers (vs. me forgetting to run them manually).
As a very basic check, I'll simply run...
php bin/console security:check
...to see what composer has to say about vulnerabilities. Ultimately I'd like to roll this output into an email or post it to a slack channel or basecamp job when the cron is run.
Problem
When I run the command from via terminal it works great. Running the command inside a controller always returns the response Lock file does not exist. I'm assuming this in reference to the composer.lock file at the root of the project. I can confirm that this file does in fact exist.
Following is the controller I'm currently using, which is adapted from this:
http://symfony.com/doc/current/console/command_in_controller.html
<?php
namespace Treetop1500\SecurityReportBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Output\BufferedOutput;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
class DefaultController extends Controller
{
public function indexAction($key)
{
if ($key != $this->getParameter('easy_cron_key')) {
throw new UnauthorizedHttpException("You are not authorized to access this page.");
}
$kernel = $this->get('kernel');
$application = new Application($kernel);
$application->setAutoExit(false);
$input = new ArrayInput(array(
'command' => 'security:check'
));
// You can use NullOutput() if you don't need the output
$output = new BufferedOutput();
$application->run($input, $output);
// return the output, don't use if you used NullOutput()
$content = $output->fetch();
// return new Response(""), if you used NullOutput()
return new Response($content);
}
}
$content always has the value "Lock file does not exist."
I realize there are probably better tools and ways to do this, however I would really like to understand why this is the generated response from in this controller action. Thank you for taking a look!
Pass absolute path to composer.lock file just like that:
php bin/console security:check /path/to/another/composer.lock
So in your example, that's would be:
$input = new ArrayInput([
'command' => 'security:check',
'lockfile' => '/path/to/another/composer.lock'
]);
Read more: SecurityCheckerCommand from SensioLabs. Optional argument is lockfile, which is checked by SecurityChecker. On line 46, they are looking for composer.lock file (default argument) and throw an exception, when they not found.
P.S. Earlier, I type the wrong parameters to array. I checked in Symfony documentation (How to Call Other Commands) and fixed the answer.
The solution to this is to pass the lockfile argument to the ArrayInput object like this:
$lockfile = $this->get('kernel')->getRootDir()."/../composer.lock";
$input = new ArrayInput(array('command'=>'security:check','lockfile'=>$lockfile));
So I have the Paypal REST API installed ( https://github.com/paypal/rest-api-sdk-php ) with Composer in my_drupal_module/lib/Drupal/ and now I want to use the namespaces in a function in my module. I understood that I need something like xautoload ( https://drupal.org/project/xautoload ) to do that so I tried something like:
$payer = new \Drupal\vendor\PayPal\Api\Payer;
with and without the first slash, and with and without parentheses at the end but it didn't work. I added:
require DIR . '/lib/Drupal/vendor/autoload.php';
but still nothing so I commented it. Meanwhile I found this: https://drupal.org/node/1976206 that explains this issue but it is unclear to me what exactly to write in hook_xautoload() or direct registration for the setup that I have. Can someone please help?
Nevermind. I solved it. Thanks to proloy03 who gave me the idea: https://drupal.org/node/2096621
You don't need xautoload to load the classes and namespace just implement hook_init to require it like so:
function my_module_init() {
require __DIR__ . '/vendor/autoload.php';
}
and then in your function write:
$payer = new PayPal\Api\Payer();
and it all works.
With xautload you can do something like this...
In mymodule.module
function mymodule_libraries_info() {
'paypal' => array(
'name' => 'PayPal SDK',
'xautoload' => function($adapter) {
$adapter->composerJson('composer.json');
}
}
Declaring this allow you to use the namespace. Like
use PayPal\Api\Amount;
Check xautoload.api.php
Your assumption that you need XAutoload to use the Paypal API installed by Composer is wrong.
The only thing you need to make any code installed by Composer available is to include the Composer autoloader in your code execution path when you need any of the provided classes. The easiest form of this is to simply require the Composer autoloader in the very first index.php (or whatever Drupal uses) file that answers every request (possibly instantiating more Drupal classes, modules and stuff).
Once the code execution comes to your own code, the autoloading allows your code to include all the classes you included with Composer.
How to use the code? Don't invent your own namespace for the existing code, it will not work. "\Drupal\vendor\PayPal\Api\Payer" sounds pretty wrong to me, I suspect the correct namespace is "\PayPal\Api\Payer". And yes, that file does indeed exist. So you have to use that.
If it still does not work, complaining the class could not be loaded, then the Composer autoloader file is not included in your scripts code path.
My problem:
require_once '/includes/aws-sdk-1.5.2/sdk.class.php';
My environment:
I have a pretty standard PHP site that uses __autoload() to grab any classes that I need. However, I now need to include the SDK to send files over to S3, but simply requiring that library seems to throw off the scope of the entire app so that any code that follows is broken.
Example:
// Save to S3
require_once '/var/www/html/system/aws-sdk-1.5.2/sdk.class.php';
$s3 = new AmazonS3();
if( ! $s3->if_bucket_exists(S3_BUCKET) )
throw new Exception('S3 bucket does not exist.');
$response = $s3->create_object(S3_BUCKET, $temp_file['s_unique_name'], array(
'fileUpload' => $_FILES['my_file']['tmp_name'],
'acl' => $s3::ACL_PUBLIC
));
// Save file
$photo = new vehicle_photo();
$photo->i_vehicle = $i_vehicle;
$photo->s_file = $temp_file['s_url'];
$photo->s_label = $_FILES['my_file']['name'];
$photo->save();
So, with the // Save to S3 snippet enabled, the following vehicle_photo class can no longer be found, in addition to all other classes that may be used after this point. If I disable it, everything works.
What's happening here?
Sounds like the autoloading mechanisms are conflicting. You might find this helpful: https://forums.aws.amazon.com/thread.jspa?threadID=85239 . Additionally, spl_autoload_register is better than plain old __autoload - consider migrating your autoloader code to that.
I would like to be able to use OOP and create new objects in my controllers in CodeIgniter. So I need to use an autoload-function:
function __autoload( $classname )
{
require_once("../records/$classname.php");
}
But how can I add that to CodeIgniter?
You can add your auto loader above to app/config/config.php. I've used a similar autoload function before in this location and it's worked quite neatly.
function __autoload($class)
{
if (strpos($class, 'CI_') !== 0)
{
#include_once(APPPATH . 'core/' . $class . EXT);
}
}
Courtesy of Phil Sturgeon. This way may be more portable. core would probably be records for you; but check your paths are correct regardless. This method also prevents any interference with loading CI_ libs (accidentally)
the User guide about Auto-loading Resources is pretty cleat about it.
To autoload resources, open the application/config/autoload.php file and add the item you want loaded to the autoload array. You'll find instructions in that file corresponding to each type of item.
I would suggest using hooks in order to add this function to your code.
Enable hooks in your config/config.php
$config['enable_hooks'] = TRUE;
In your application/config/hooks.php add new hook on the "pre_system" call, which happens in core/CodeIgniter.php before the whole system runs.
$hook['pre_system'] = array(
0 => array(
'function' => 'load_initial_functions',
'filename' => 'your_hooks.php',
'filepath' => 'hooks'
)
);
Then in the hooks folder create 2 files:
First: application/hooks/your_functions.php and place your __autoload function and all other functions that you want available at this point.
Second: application/hooks/your_hooks.php and place this code:
function load_initial_functions()
{
require_once(APPPATH.'hooks/your_functions.php');
}
This will make all of your functions defined in your_functions.php available everywhere in your code.
I'm pretty much newbie in Zend Framework action helpers and I am trying to use them with no success (I read a bunch of posts about action helpers, including http://devzone.zend.com/article/3350 and found no solution in like 8 hours). I used Zend Tool to setup my project and the name of the helper is Action_Helper_Common. No matter what I do, I get following error "Fatal error: Class 'Action_Helper_Common' not found". Currently, I have things set up like this:
zf version: 1.11.3
helper name: Action_Helper_Common
helpers location:
/application/controllers/helpers/Common.php
In Bootstrap.php i have following function:
protected function _initActionHelpers() {
Zend_Controller_Action_HelperBroker::addPath(APPLICATION_PATH . '/controllers/helpers', 'Action_Helper');
Zend_Controller_Action_HelperBroker::addHelper(
new Action_Helper_Common(null, $session)
);
}
I also tried this without success (it was defined in Bootstrap.php before _initActionHelpers):
protected function _initAutoloader() {
$moduleLoader = new Zend_Application_Module_Autoloader(array(
'namespace' => '',
'basePath' => APPLICATION_PATH . '/controllers/helpers'));
return $moduleLoader;
}
So what am I doing wrong?!?! PLZ help, I am desperate and about to give up :)
You got error because you haven't setup autoloader for Action_Helper_*
Resource autoloader
Helper broker uses plugin loader to load helpers based on paths and prefixes you specified to it. That is why ::getHelper() can find your helper
you dont need to do (so remove it)
Zend_Controller_Action_HelperBroker::addHelper(
new Action_Helper_Common(null, $session)
); ,
since you already did
Zend_Controller_Action_HelperBroker::addPath(APPLICATION_PATH . '/controllers/helpers', 'Action_Helper');
when you will do
$myhelper = $this->getHelper('Common');
in your controller zf will lookinto directory /controllers/helpers/ for class name Action_Helper_Common and create an instance for you and return it.
For some reason the following line didn't work for me as well:
Zend_Controller_Action_HelperBroker::addHelper( new Action_Helper_Common() );
I just keep getting a 'Class not found' error each time I'm creating a new helper object explicitly.
This is what works for me:
Zend_Controller_Action_HelperBroker::getHelper('Common');
In this case, new Action_Helper_Common object gets created and is registered with Helper Broker.
Not sure though if it works for you, since you have a parameterized constructor.