I have a file named
Helper.php and I have put it in composer.
"autoload": {
"files": [
"app/Http/Helper.php",
"app/Notification.php"
]
},
You can see that I have also put a model that is Notification model. but when I call this Notification in Helper.php it says class Notification not found..
function notify()
{
$notify = new App\Notifcation;
$notify = new Notifcation; //Also tried this
}
First of all you don't need to add it in composer.
Secondly, check what you have written twice thrice because there can be typos that will stop your program from being executed
remove "app/Notification.php" from composer.json and dump-autoload it. Then use like this.
function notify()
{
$notify = new App\Notification;
}
If you add this Notification Model in composer then it will always be autoloaded even if it is not used thus putting unnecessary pressure on your project.
Hope this helps
You have a typo in Notifcation. Try this:
function notify()
{
$notify = new Notification;
}
Write use App\Notification in your Helper.php
than
$notify = new Notification();
Or you can use this:
$notify = new \App\Notification;
And just in case check your namespaces
Related
I am trying to use a library of classes within Laravel 8. I am having difficulty getting the classes to load correctly. I created a new folder within the App folder called DigiSigner, which is the external library's namespace.
App\DigiSigner
DigiSignerClient.php
\libs
BaseRequest.php
Branding.php
ClassLoader.php
Config.php
Curler.php
DigiSignerException.php
DigiSignerResponse.php
Document.php
DocumentField.php
DocumentFields.php
ExistingField.php
ExportObject.php
Field.php
SignatureRequest.php
Signer.php
I created a controller that looks like this
class SignPDFController extends Controller
{
public function getPDF()
{
$client = new DigiSignerClient('client_key');
$request = new SignatureRequest;
$request->setEmbedded(true);
$request->setSendEmails(false);
$template = Document::withID('document_id');
$template->setTitle('Site Title');
$request->addDocument($template);
$signer = new Signer('user#email.com');
$signer->setRole('Signer 1');
$template->addSigner($signer);
$initials = new ExistingField('key');
$initials->setContent('VS');
$signer->addExistingField($initials);
$response = $client->sendSignatureRequest($request);
foreach ($response->getDocuments() as $document) {
foreach ($document->getSigners() as $signer) {
$signDocumentUrl = $signer->getSignDocumentUrl();
}
}
}
}
The DigiSignerClient and the SignatureRequest classes seem to load fine, but the SignatureRequest needs to load the ExportObject class to extend it.
namespace App\DigiSigner;
use App\DigiSigner\libs\ExportObject;
class SignatureRequest extends ExportObject {
I end up with an error like the following.
Error Class 'App\DigiSigner\libs\ExportObject' not found
Namespaces and use are a little fuzzy for me. If someone can point me in the right direction, I would be delighted.
I believe I figured it out. All the files in the subdirectory needed the namespace changed to App\DigiSigner\libs.
Check ExportObject.php namespace.
Class not found, apparently. I've tried various things but nothing works.
Composer:
"autoload": {
"psr-4": {
"App\\": "application/"
}
}
File structure:
https://i.imgur.com/h9wOEqI.png
<?php
namespace App\Library\Classes;
defined('START') or exit('We couldn\'t process your request right now.');
class Application
{
private static $libraries = array();
public static function get($library) {
if (isset(self::$libraries[$library]) && isset(self::$classes[$library])) {
return self::$libraries[$library];
}
$fixedLibrary = str_replace('.', '/', $library);
$file = ROOT . '/application/library/classes/' . strtolower($fixedLibrary) . '.php';
self::$libraries[$library] = $library;
$declared = get_declared_classes();
$workingClass = end($declared);
self::$libraries[$library] = new $workingClass();
return self::$libraries[$library];
}
}
?>
Error is on this line:
Application::get('test')->test();
Yet, if I change it to this, it works:
include ROOT . '/application/Library/Application.php';
App\Library\Classes\Application::get('test')->test();
The PSR4 is not built-in part or PHP, you need an implementation of autoloader to use this standard such as provided by the Composer.
When you install or update depedencies, composer generates the relevant code of autoloading, but you can directly update it by the command dump-autoload, as #jibsteroos said. Next you should explicitly include the file vendor/autoload.php in the entry point of your application.
Also, error message says about class Application, but you should add the use statement at first:
use App\Library\Classes\Application;
Application::get('test')->test();
Or use the fully qualified class name (class name with namespace prefix):
\App\Library\Classes\Application::get('test')->test();
I'm trying to run a job queue to create a PDF file using SlmQueueBeanstalkd and DOMPDFModule in ZF".
Here's what I'm doing in my controller:
public function reporteAction()
{
$job = new TareaReporte();
$queueManager = $this->serviceLocator->get('SlmQueue\Queue\QueuePluginManager');
$queue = $queueManager->get('myQueue');
$queue->push($job);
...
}
This is the job:
namespace Application\Job;
use SlmQueue\Job\AbstractJob;
use SlmQueue\Queue\QueueAwareInterface;
use SlmQueue\Queue\QueueInterface;
use DOMPDFModule\View\Model\PdfModel;
class TareaReporte extends AbstractJob implements QueueAwareInterface
{
protected $queue;
public function getQueue()
{
return $this->queue;
}
public function setQueue(QueueInterface $queue)
{
$this->queue = $queue;
}
public function execute()
{
$sm = $this->getQueue()->getJobPluginManager()->getServiceLocator();
$empresaTable = $sm->get('Application\Model\EmpresaTable');
$registros = $empresaTable->listadoCompleto();
$model = new PdfModel(array('registros' => $registros));
$model->setOption('paperSize', 'letter');
$model->setOption('paperOrientation', 'portrait');
$model->setTemplate('empresa/reporte-pdf');
$output = $sm->get('viewPdfrenderer')->render($model);
$filename = "/path/to/pdf/file.pdf";
file_put_contents($filename, $output);
}
}
The first time you run it, the file is created and the work is successful, however, if you run a second time, the task is buried and the file is not created.
It seems that stays in an endless cycle when trying to render the model a second time.
I've had a similar issue and it turned out it was because of the way ZendPdf\PdfDocument reuses it's object factory. Are you using ZendPdf\PdfDocument?
You might need to correctly close factory.
class MyDocument extends PdfDocument
{
public function __destruct()
{
$this->_objFactory->close();
}
}
Try to add this or something similar to the PdfDocument class...
update : it seem you are not using PdfDocument, however I suspect this is the issue is the same. Are you able to regenerate a second PDF in a normal http request? It is your job to make sure the environment is equal on each run.
If you are unable to overcome this problem a short-term quick solution would be to set max_runs configuration for SlmQueue to 1. That way the worker is stopped after each job and this reset to a vanilla state...
I've written a simple display_messages() function that will search Session::get('errors') for flash data and echo it to the screen.
Where do I put this function? In Codeigniter, you had a helpers folder where you could stick all your little global helper methods.
As Usman suggested,
create a file /application/libraries/demo.php
define a class Demo() { inside it
call the function like so: {{ Demo::display() }}
Works because libraries and models are autoloaded in start.php line 76. I believe that filenames must match Classnames (note capital).
<?php
class Demo {
public static function display() {
if( !$message = Session::get('errors'))
$message = 'No Errors';
echo "<pre>print_r($message)</pre>";
}
}
Can't quite figure out why I had a problem using the classname Common, there may be a conflict (you could define a namespace if this were important)...
Create a folder helpers within your app folder and create a file application_helper.php. With such code:
// app/helpers/application_helper.php
function display_messages()
{
exit('Yes');
}
Then open your composer.json file in root. autoload app/helpers/application_helper.php with composer files.
"autoload": {
....
"files": [
"app/helpers/application_helper.php"
]
Done, you can now call display_messages().
Some autoloaders may require you to run composer dump command for the first time.
Thank you memeLab provided a very useful answer which helped me a lot. I just wanted to expand on his answer as the "libraries" folder was not an auto load directory, at least not in the release/current version of L4 I am using. Also the start.php seems to have been expanded to be the start folder with global.php, local.php, and artisan.php.
So to use your own classes for separate libraries or helpers with the L4 lazy auto loader you just have to include whichever folder you want to store these in to the global.php. For example I added a libraries folder to the directory list.
ClassLoader::addDirectories(array(
app_path().'/commands',
app_path().'/controllers',
app_path().'/models',
app_path().'/database/seeds',
// this a custom path
app_path().'/libraries',
));
Then whatever class you define in that folder as classname.php can be called via CLASSNAME::methodName($someVar); in your controllers.
class CLASSNAME {
public static function methodName($someVar=NULL) {
// whatever you want to do...
return $message;
}
}
So in this fashion you can create a helper class and define different methods to use throughout your controllers. Also be careful defining regular functions outside of your Class in this manner will cause you grief because they will not work (because the class is not always loaded). (for example someFunctionName($someVar); instead of CLASSNAME::methodName($someVar);) If you want to create functions in this manner you would need to make sure the is loaded, however I will not elaborate on this because it is better practice to use the lazy loader classes for such things so you only load the classes you really need.
Thanks again to memeLab and Usman, I would not have gotten as far without their answers. :)
For loading Classes:
Create app/libraries/class/Message.php, and add class in file
class Message {
public static function display() {
}
}
Add "app/libraries/class" to composer.json
"autoload": {
"classmap": [
"app/commands",
"app/controllers",
"app/models",
"app/database/migrations",
"app/database/seeds",
"app/tests/TestCase.php",
"app/libraries/class"
]
},
Finally run composer dump-autoload in command line.
You can access that by Message::display()
For loading plain non-object php Functions:
Create app/libraries/function/display_messages.php, and add function in file
function display_messages() {
}
add one line in start/global.php
require app_path().'/libraries/function/display_messages.php';
You can access that just by display_messages()
Add this in app/start/global.php
require app_path().'/config/autoload.php';
require app_path().'/start/loader.php';
App::instance('loader',new loader($autoload));
create a new file loader.php in app/start and add:
class loader{
private $helpers = array();
public $autoload = array(
'helpers' => array()
);
function __construct($autoload = array()) {
if (!empty($autoload))
$this->autoload = $autoload;
foreach ($this->autoload as $key => $value)
{
$function = strtolower($key);
$this->$function($value);
}
}
function helpers($helpers=array())
{
if (!is_array($helpers))
$helpers = explode(",",$helpers);
foreach ($helpers as $key => $value) {
$this->helper($value);
}
}
function helper($helper = '',$path = '/')
{
$folder = app_path().'/helpers'.$path;
if (file_exists($folder.$helper.'.php') && !in_array($helper, $this->helpers)){
$this->helpers[] = $helper;
require $folder.$helper.'.php';
}
else{
$segments = explode('/',$helper);
if (is_dir($folder.$segments[0])){
array_shift($segments);
$this->helper($segments,$path.$segments[0].'/');
}
}
}
}
create a new file autoload.php in app/config and add:
$autoload['helpers'] = array('functions'); // my autoload helpers!
create a new folder helpers in app/ , add your helper files. ( es. myhelper.php )
function myhelper()
{
echo 'helper';
}
in your controller add:
App::make('loader')->helper('myhelper');
myhelper();
In L3, I would normally create a application/libraries/helpers.php file, and require_once() it in my application/start.php. Similar to how L3 has a laravel/helpers.php file.
I'm assuming there is something similar you can do in L4.
EDIT: Just looking at the source, app/start/local.php seems like it might be the place.
I used this tutorial and i think is the easiest method: http://laravel-recipes.com/recipes/50/creating-a-helpers-file
First create the file app/helpers.php
Then either load it at the bottom of app\start\global.php as follows.
// at the bottom of the file
require app_path().'/helpers.php';
Or change your composer.json file and dump the autoloader.
{
"autoload": {
"files": [
"app/helpers.php"
]
}
}
$ composer dump-auto
then you can write your functions in helpers.php and call them from anywhere
function myfunction($result){
return $result;
}
open root_folder/vendor/laravel/framework/src/Illuminate/Support/helpers.php
and you can add your function
if ( ! function_exists('display_messages'))
{
function display_messages()
{
return ...
}
}
I'm using PHP 5.3's class_alias to help process my Symfony 1.4 (Doctrine) forms. I use a single action to process multiple form pages but using a switch statement to choose a Form Class to use.
public function executeEdit(sfWebRequest $request) {
switch($request->getParameter('page')) {
case 'page-1':
class_alias('MyFormPage1Form', 'FormAlias');
break;
...
}
$this->form = new FormAlias($obj);
}
This works brilliantly when browsing the website, but fails my functional tests, because when a page is loaded more than once, like so:
$browser->info('1 - Edit Form Page 1')->
get('/myforms/edit')->
with('response')->begin()->
isStatusCode(200)->
end()->
get('/myforms/edit')->
with('response')->begin()->
isStatusCode(200)->
end();
I get a 500 response to the second request, with the following error:
last request threw an uncaught exception RuntimeException: PHP sent a warning error at /.../apps/frontend/modules/.../actions/actions.class.php line 225 (Cannot redeclare class FormAlias)
This makes it very hard to test form submissions (which typically post back to themselves).
Presumably this is because Symfony's tester hasn't cleared the throughput in the same way.
Is there a way to 'unalias' or otherwise allow this sort of redeclaration?
As an alternate solution you can assign the name of the class to instantiate to a variable and new that:
public function executeEdit(sfWebRequest $request) {
$formType;
switch($request->getParameter('page')) {
case 'page-1':
$formType = 'MyFormPage1Form';
break;
...
}
$this->form = new $formType();
}
This doesn't use class_alias but keeps the instantiation in a single spot.
I do not know for sure if it is possible, but judging from the Manual, I'd say no. Once the class is aliased, there is no way to reset it or redeclare it with a different name. But then again, why do use the alias at all?
From your code I assume you are doing the aliasing in each additional case block. But if so, you can just as well simply instantiate the form in those blocks, e.g.
public function executeEdit(sfWebRequest $request) {
switch($request->getParameter('page')) {
case 'page-1':
$form = new MyFormPage1Form($obj);
break;
...
}
$this->form = $form;
}
You are hardcoding the class names into the switch/case block anyway when using class_alias. There is no advantage in using it. If you wanted to do it dynamically, you could create an array mapping from 'page' to 'className' and then simply lookup the appropriate class.
public function executeEdit(sfWebRequest $request) {
$mapping = array(
'page-1' => 'MyFormPage1Form',
// more mappings
);
$form = NULL;
$id = $request->getParameter('page');
if(array_key_exists($id, $mapping)) {
$className = $mapping[$id];
$form = new $className($obj);
}
$this->form = $form;
}
This way, you could also put the entire mapping in a config file. Or you could create FormFactory.
public function executeEdit(sfWebRequest $request) {
$this->form = FormFactory::create($request->getParameter('page'), $obj);
}
If you are using the Symfony Components DI Container, you could also get rid of the hard coded factory dependency and just use the service container to get the form. That would be the cleanest approach IMO. Basically, using class_alias just feels inappropriate here to me.
function class_alias_once($class, $alias) {
if (!class_exists($alias)) {
class_alias($class, $alias);
}
}
This doesn't solve the problem itself, but by using this function it is ensured that you don't get the error. Maybe this will suffice for your purpose.