Zend framework 2: class_exists('mPDF') returns true yet new mPDF() fails - zend-framework2

I want to use mPDF in a controller as follows (test scenario):
function indexAction() {
require_once('libraries/mpdf/mpdf.php');
var_dump(class_exists('mPDF')); //prints true
$mpdf = new mPDF(); //fails with 'class not found in Application/Controller (current namespace)
}
The class mPDF is declared inside the mpdf.php file and i've checked if the file gets loaded and it does.

To solve this you have to add \ infront of the class name to reset namespace
function indexAction() {
require_once('libraries/mpdf/mpdf.php');
var_dump(class_exists('mPDF')); //prints true
$mpdf = new \mPDF(); //fails with 'class not found in Application/Controller (current namespace)
}
error message is the clue to this
//fails with 'class not found in Application/Controller (current namespace)
I however dont know why the class_exist returns true. It did not do that when i had my class in autoload_classmap.php but when i require_once i got the same problem.
also if you dont want to require_once the php file in the function you can add it to class mapp file at the root of the module
<?php
// Generated by ZF2's ./bin/classmap_generator.php
return array(
'mPDF' => __DIR__ . 'path/to/file/mpdf.php',
);
I do this with PHPMailer

Related

Adding Value Options to Select Element

I'm trying to set multiple values for a select object with Zend Framework 2's form class but it's only passing one value. Here is my code:
public function addphotosAction()
{
$identity = $this->identity();
$files = array();
$album_name = array();
foreach (glob(getcwd() . '/public/images/profile/' . $identity . '/albums/*', GLOB_ONLYDIR) as $dir) {
$album_name = basename($dir);
$files[$album_name] = glob($dir . '/*.{jpg,png,gif,JPG,PNG,GIF}', GLOB_BRACE);
}
$form = new AddPhotosForm();
$form->get('copy-from-album')->setValueOptions(array($album_name));
return new ViewModel(array('form' => $form, 'files' => $files));
}
I know it has to do with $album_name but am at a loss about how to use it to grab all the directories (if I try to write to $album_name via []), I get an warning of
`Warning: Illegal offset type in C:\xampp\htdocs\module\Members\src\Members\Controller\ProfileController.php on line 197`
which is the $files[$album_name] = glob($dir . '/*.{jpg,png,gif,JPG,PNG,GIF}', GLOB_BRACE); line.
As I said, I am at a loss about how to edit this to grab all the directories.
Any help would be appreciated.
Thanks!
here is a screenshot of what I am trying to describe: http://imgur.com/OGifNG9
(there is more than one directory that exists but only one is being listed in the select menu).
I really recommend to do it with a factory. With a factory you 'll write this code once and can use it everywhere else in your code. For object orientated reasons, in which everything should be an object, I recommend using PHP 's own DirectoryIterator class instead of glob. The code in the controller should be kept as small as possible. Please have a look at the following example code.
The Form Factory with the Directory Iterator
The form factory intializes the form class with everything you need for the form instance for you, so this code won 't show up in the controller. You can re-use it for an inherited edit form for example.
<?php
namespace Application\Form\Factory;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use Application\Form\AddPhotosForm;
class AddPhotosFormFactory implements FactoryInterface
{
public function createService(ServiceLocatorInterface $oServiceLocator)
{
$oParentLocator = $oServiceLocator->getServiceLocator();
// please adjust the dir path - this is only an example
$aDirectories = [];
$oIterator = new \DirectoryIterator(__DIR__);
// iterate and get all dirs existing in the path
foreach ($oIterator as $oFileinfo) {
if ($oFileinfo->isDir() && !$oFileinfo->isDot()) {
$aDirectories[$oFileinfo->key()] = $oFileinfo->getFilename();
}
}
// set option attribute for select element with key => value array of found dirs
$oForm = new AddPhotosForm();
$oForm->get('mySelectElement')
->setAttributes('options', $aDirectories);
return $oForm;
}
}
That 's all for the factory itself. The only thing you have to do is writing it down in your module.config.php file.
...
'form_elements' => [
'factories' => [
AddPhotosForm::class => AddPhotosFormFactory::class,
],
],
...
Using ::class not just cleans things up, it will lead to using fewer strings and this makes things easy to remember in an IDE with autocompletion for class names.
The Controller
With the factory we cleaned up the controller. In a controller code should be as small as possible. Using factories is the solution for many problems, which may happen in a later process of coding. So keep it always clean and simple.
...
public function indexAction()
{
$oForm = $this->getServiceManager()
->get('FormElementManager')
->get(AddPhotosForm::class);
return [
'form' => $oForm,
}
}
That 's all for the controller so far. Your select element was populated in the factory and your controller is easy to understand and as small as it should be.

Zend Framework index.php. __DIR__ and ServiceManger

C:\Program Files (x86)\Zend\Apache2\htdocs\zf2-tutorial\public\index.php:
<?php
/**
* This makes our life easier when dealing with paths. Everything is relative
* to the application root now.
*/
chdir(dirname(__DIR__));
// Decline static file requests back to the PHP built-in webserver
if (php_sapi_name() === 'cli-server' && is_file(__DIR__ . parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH))) {
return false;
}
// Setup autoloading
require 'init_autoloader.php';
// Run the application!
Zend\Mvc\Application::init(require 'config/application.config.php')->run();
If I place a file in the same directory called console.php:
<?php
echo __DIR___
?>
and run:
php console.php
The output is:
C:\Program Files (x86)\Zend\Apache2\htdocs\zf2-tutorial\public
Clearly this seems to be the wrong directory as 'init_autoloader.php' is actually located here:
C:\Program Files (x86)\Zend\Apache2\htdocs\zf2-tutorial
Also my book says that the line:
Zend\Mvc\Application::init(require 'config/application.config.php')->run();
calls the bootstrap() method of the Zend\Mvc\Application. I'm not sure how a call to init() translates to a call to bootstrap() could someone please explain this to me?
My book also says that the call to init takes care of instantiating a new ServiceManager object although I'm not sure how because I see nothing in the bootstrap method of the Application model that has anything to do at all with ServiceManager. Could someone explain this to me?
Thank you for posting...
For reference zf2-tutorial/Module/Application/Module.php
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* #link http://github.com/zendframework/ZendSkeletonApplication for the canonical source repository
* #copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* #license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Application;
use Zend\Mvc\ModuleRouteListener;
use Zend\Mvc\MvcEvent;
class Module
{
public function onBootstrap(MvcEvent $e)
{
$eventManager = $e->getApplication()->getEventManager();
$moduleRouteListener = new ModuleRouteListener();
$moduleRouteListener->attach($eventManager);
}
public function getConfig()
{
return include __DIR__ . '/config/module.config.php';
}
public function getAutoloaderConfig()
{
return array(
'Zend\Loader\StandardAutoloader' => array(
'namespaces' => array(
__NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
),
),
);
}
}
Clearly this seems to be the wrong directory as 'init_autoloader.php' is actually located here: C:\Program Files (x86)\Zend\Apache2\htdocs\zf2-tutorial
The output from your console.php is different because in index.php you'll see this line ...
chdir(dirname(__DIR__));
This effectiveley changes up one directory to C:\Program Files (x86)\Zend\Apache2\htdocs\zf2-tutorial which is the root of the application and the same folder in which init_autoloader.php is located.
Also my book says that the line: Zend\Mvc\Application::init(require 'config/application.config.php')->run(); calls the bootstrap() method of the Zend\Mvc\Application.
You are confusing the Zend\Mvc\Application with the skeleton application module named Application. They are not the same thing.
The bootstrapping being referred to by your book is happening here in the code ...
https://github.com/zendframework/zf2/blob/master/library/Zend/Mvc/Application.php#L247-L261
As you can see it's a static method, which instantiates the ServiceManager and proceeds to set up services before finally bootstrapping the application here ...
https://github.com/zendframework/zf2/blob/master/library/Zend/Mvc/Application.php#L136-L158
For further reading I'd suggest familiarizing yourself with the MVC layer by reading the docs here
http://framework.zend.com/manual/2.3/en/modules/zend.mvc.intro.html

Why does the ZF2 autoloader build the path wrongly?

I have an application with some modules. One of them is CourseSearch. Now I want to add a further one, the SportsPartnerSearch. Since these two modules are very similar to each other, I simply "cloned" / copied the CourseSearch and replaced all "Course" with "SportsPartner" (in all variations: $course to $sportsPartner, course-...phtml to sports-partner-...phtml etc.), in order to edit the logic in the second step. Now I'm getting following errors:
Warning:
require_once(/path/to/project/module/SportsPartnerSearch//src/CourseSearch/View/Helper/CourseSearchForm.php):
failed to open stream: No such file or directory in
/path/to/project/vendor/zendframework/zendframework/library/Zend/Loader/ClassMapAutoloader.php
on line 140
Fatal error: require_once(): Failed opening required
'/path/to/project/module/SportsPartnerSearch//src/CourseSearch/View/Helper/CourseSearchForm.php'
(include_path='.:/usr/share/php:/usr/share/pear') in
/path/to/project/vendor/zendframework/zendframework/library/Zend/Loader/ClassMapAutoloader.php
on line 140
Why is the path to the file being built in such strange way: /path/to/project/module/SportsPartnerSearch//src/CourseSearch/View/Helper/CourseSearchForm.php? Where did I do a mistake?
Some additional information.
The class, that cannot be found because the wron path is CourseSearch\View\Helper\CourseSearchForm in the CourseSearch module. It can be found, when I deactivate the new module SportsPartnerSearch, that contains the class SportsPartnerSearch\View\Helper\SportsPartnerSearchForm.
The CourseSearchForm view helper is instanciated in the CourseSearchForm\Module
class Module {
public function getViewHelperConfig() {
return array(
'factories' => array(
'courseSearchForm' => function($serviceManager) {
$helper = new View\Helper\CourseSearchForm(array('render' => true, 'redirect' => false));
// ERROR. This code is not executed anymore.
$helper->setViewTemplate('course-search/course-search/course-search-form');
$courseSearchForm = $serviceManager->getServiceLocator()->get('CourseSearch\Form\CourseSearchForm');
$helper->setCourseSearchForm($courseSearchForm);
return $helper;
}
)
);
}
}
And called in the layout file:
echo $this->courseSearchForm();
The SportsPartnerSearch\View\Helper\SportsPartnerSearchForm is instanciated in the same way in the SportsPartnerSearch\Module#getViewHelperConfig() and is not called yet.
Have you generated a classmap? Check the autoload_classmap.php file in both the CourseSearch and the SportsPartnerSearch modules. I guess you still have an old classmap lying around. I think the problem is hidden inside the classmap because of the error in the ClassMapAutoloader from Zend, and not the standard autoloader.
You can generate a new classmap with the classmap generator provided in ZF2 (assuming you load it via Composer) with:
cd module/SportsPartnerSearch
../../vendor/bin/classmap_generator.php
This will generate a new classmap file inside the SportsPartnerSearch module.

Zend Framework 2 ClassMapAutoloader error

I am very new to Zend Framework 2 and am using the book “Web Development with Zend Framework 2” by Michael Romer as my guide. I’m at the end of chapter 5 and the subject of the ClassMapAutoloader is presented. The conclusion of the discussion is that my Helloworld module now has the file and directory structure of ->
Module.php
autoload_classmap.php
autoload_function.php
autoload_register.php
config/
module.config.php
public/
images/
css/
js/
src/
Helloworld/
Controller/
IndexController.php
views/
Helloworld/
Index/
index.phtml
As far as I can tell the files of interest that setup Classmap autoloading are Module.php, autoload_classmap.php, autoload_function.php, autoload_register.php. The contents of these files are
Module.php ->
<?php
namespace Helloworld;
Class Module {
public function getAutoloaderConfig() {
return array(
'Zend\Loader\ClassMapAutoloader' => array(
__DIR__ . '/autoload_classmap.php'
),
'Zend\Loader\StandardAutoloader' => array(
'namespaces' => array(
__NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__
)
)
);
}
public function getConfig() {
return include __DIR__ . '/config/module.config.php';
}
}
autoload_function.php ->
<?php
return function ($class) {
static $classmap = null;
if ($classmap === null) {
$classmap = include __DIR_ . '/autoload_classmap.php';
}
if (!isset($classmap[$class])) {
return false;
}
return include_once $classmap[$class];
};
autoload_register.php ->
<?php
spl_autoload_register(include __DIR__ . '/autoload_function.php');
autoload_classmap.php ->
<?php
//require_once 'autoload_register.php';
return array();
This all works when I have that blank array return in autoload_classmap.php BUT in the book the example has require_once 'autoload_register.php';. When I uncomment that line I get the following error ->
The error is -> [Tue Jun 18 16:29:20 2013] [error] [client 199.82.163.121] PHP Fatal error: Uncaught exception 'Zend\Loader\Exception\InvalidArgumentException' with message 'Map file provided does not return a map. Map file: "/var/www/ZendApp/module/Helloworld/autoload_classmap.php"' in /var/www/ZendApp/vendor/zendframework/zendframework/library/Zend/Loader/ClassMapAutoloader.php:88\nStack trace:\n#0 /var/www/ZendApp/vendor/zendframework/zendframework/library/Zend/Loader/ClassMapAutoloader.php(117): Zend\Loader\ClassMapAutoloader->registerAutoloadMap('/var/www/ZendAp...')\n#1 /var/www/ZendApp/vendor/zendframework/zendframework/library/Zend/Loader/ClassMapAutoloader.php(60): Zend\Loader\ClassMapAutoloader->registerAutoloadMaps(Array)\n#2 /var/www/ZendApp/vendor/zendframework/zendframework/library/Zend/Loader/ClassMapAutoloader.php(46): Zend\Loader\ClassMapAutoloader->setOptions(Array)\n#3 /var/www/ZendApp/vendor/zendframework/zendframework/library/Zend/Loader/AutoloaderFactory.php(100): Zend\Loader\ClassMapAutoloader->__construct(Array)\n#4 /var/www/ZendApp/vendor/zendframework/zendframework/library/Zend/M in /var/www/ZendApp/vendor/zendframework/zendframework/library/Zend/Loader/ClassMapAutoloader.php on line 88
I know that returning the blank array causes the getAutoloaderConfig() in the Module class of Module.php to default to the StandardAutoloader and thus it works but Why? I’d really like to get the ClassMapAutoloader to do its thing in this example. How do I get this to work? Thanks in advance for your reply.
James Eastman
There is no such thing as requiring the autoloader register function in the classmap file. That is not even in the books.
You can generate the autoloader classmap with the classmap generator provided within Zend Framework 2. You can generate the autoload_classmap.php file so it is populated with all the php classes in your module.
Usage:
$ cd module/MyModule
$ ../../vendor/zendframework/zendframework/bin/classmap_generator.php -w
This works in the case you loaded Zend Framework 2 with composer, which loads the library in the vendor/ directory.
in Module.php after name add the two lines of code!
namespace Helloworld;
use Zend\Mvc\ModuleRouteListener;
use Zend\Mvc\MvcEvent;

ZfcUser extend User class with additional get function

I'm new to the Zend2 Framework and have installed ZfcUser with an added database column which I would like to access through:
<?php echo $this->zfcUserIdentity()->getOrg(); ?>
Any help on extending the User Class to access this variable would be greatly appreciated.
Ryan
Extend the ZfcUser user entity to include your new property and accessors. You'll need to do this in your own module, or if you're using the skeleton app, in the Application module will work.
<?php
namespace Application\Entity;
use ZfcUser\Entity\User;
class MyUser extends User
{
protected $org;
public function setOrg($org)
{
$this->org = $org;
return $this;
}
public function getOrg()
{
return $this->org;
}
}
Copy vendor/ZfcUser/config/zfcuser.global.php.dist to /config/autoload/zfcuser.global.php
Open the file you just copied in your editor, and find the section below
/**
* User Model Entity Class
*
* Name of Entity class to use. Useful for using your own entity class
* instead of the default one provided. Default is ZfcUser\Entity\User.
* The entity class should implement ZfcUser\Entity\UserInterface
*/
//'user_entity_class' => 'ZfcUser\Entity\User',
uncomment the line, and replace the value with the fully qualified class name of the MyUser entity you created
'user_entity_class' => 'Application\Entity\MyUser',
Then try accessing your method
<?php echo $this->zfcUserIdentity()->getOrg(); ?>

Resources