I am using CakePdf to my project. I have install it via composer. But it is not loading the document.
Check error.log file. Nothing found.
Browser send the following message:
Firefox:
This pdf document might not be displayed correctly.
Chrome:
Error
Failed to load PDF document.
Here is my code:
// AppController.php
class AppController extends Controller
{
public function initialize()
{
parent::initialize();
$this->loadComponent('RequestHandler');
$this->loadComponent('Flash');
}
}
// bootstrap.php
Configure::write('CakePdf', [
'engine' => 'CakePdf.mPdf',
'margin' => [
'bottom' => 15,
'left' => 50,
'right' => 30,
'top' => 45
],
'orientation' => 'landscape',
'pageSize' => 'Legal',
'download' => true
]);
Plugin::load('CakePdf', ['bootstrap' => true, 'routes' => true]);
// routes.php
Router::scope('/', function (RouteBuilder $routes) {
// enabled extensions
$routes->addExtensions(['pdf']);
}
// ProductsController.php
public function viewPdf($id = null)
{
$this->viewBuilder()->options([
'pdfConfig' => [
'orientation' => 'portrait',
'filename' => 'Invoice_' . $id
]
]);
}
I have created Template/Products/pdf/view_pdf.ctp and Template/Layout/pdf/default.ctp
I cakephp version is 3.5.2
I couldn't get, where is the probleme. Please help me.
Related
I have started the latest tutorial for Laminas.
The routing for a new module called Provider is not working
A 404 error occurred
Page not found.
The requested URL could not be matched by routing.
on looking at my Module.php code I see:
getConfig() is not called but
getServiceConfig() and getControllerConfig() are.
getConfig in the Application module is not called either
<?php
namespace Provider;
use Laminas\Db\Adapter\AdapterInterface;
use Laminas\Db\ResultSet\ResultSet;
use Laminas\Db\TableGateway\TableGateway;
use Laminas\ModuleManager\Feature\AutoloaderProviderInterface;
use Laminas\ModuleManager\Feature\ConfigProviderInterface;
class Module implements ConfigProviderInterface, AutoloaderProviderInterface
{
public function getConfig()
{
die ("getConfig");
return include __DIR__ . '/../config/module.config.php';
}
public function getAutoloaderConfig()
{
//die ("getAutoloaderConfig");
//return array(
// 'Laminas\Loader\StandardAutoloader' => array(
// 'namespaces' => array(
// __NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
// ),
// ),
//);
}
public function getServiceConfig()
{
//die ("getServiceConfig");
return [
'factories' => [
Model\ProviderTable::class => function($container) {
$tableGateway = $container->get(Provider\ProviderTableGateway::class);
return new Model\ProviderTable($tableGateway);
},
Model\ProviderTableGateway::class => function ($container) {
$dbAdapter = $container->get(AdapterInterface::class);
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new Model\Album());
return new TableGateway('provider', $dbAdapter, null, $resultSetPrototype);
},
],
];
}
public function getControllerConfig()
{
//die ("getControllerConfig");
return [
'factories' => [
Controller\ProviderController::class => function($container) {
return new Controller\ProviderController(
$container->get(Model\ProviderTable::class)
);
},
],
];
}
}
You need to enable development mode. run composer development-enable to active development mode.
Maybe the composer json is not updated (my-application/composer.json)
"autoload": {
"psr-4": {
"Application\\": "module/Application/src/",
"Provider\\": "module/Provider/src/"
}
},
Update autoload classmap:
composer dump-autoload
https://docs.laminas.dev/tutorials/getting-started/modules/#autoloading
Have you added router configuration?
In your attached code above you have the following function :
public function getConfig()
{
//die ("getConfig"); // BE SURE YOU REMOVE THIS LINE
return include __DIR__ . '/../config/module.config.php';
}
it's include file for additional settings. in this file "/../config/module.config.php" you should add your router configuration. It should look like this:
return [
//... other setting
'router' => [
'routes' => [
// Literal route named "home"
'home' => [
'type' => 'literal',
'options' => [
'route' => '/',
'defaults' => [
'controller' => 'Application\Controller\IndexController',
'action' => 'index',
],
],
],
// Literal route named "contact"
'contact' => [
'type' => 'literal',
'options' => [
'route' => 'contact',
'defaults' => [
'controller' => 'Application\Controller\ContactController',
'action' => 'form',
],
],
],
],
],
];
more reading can be found https://docs.laminas.dev/laminas-router/routing/#simple-example-with-two-literal-routes
As mentioned before any time you add a custom module you will need to add an entry for the autoloader in composer.json and run the dump-autoload. You will also need to add an entry in the root level /config/modules.config.php file. Is there currently an entry for Application? If memory serves and your working from the examples the last two should be Application, then Album. Verify those are there and that the application is in development mode. You can check the current mode with "composer development-status". Just check composer.json in the top level and look for the "scripts" entry. The key is the command to pass to composer.
Also, be mindful of using the interfaces when configuring the application in the Module class. The Module feature methods are reserved for closures as they will not be cached when you disable development mode. Instead use the corresponding service manager array keys. that can be found here:
Service manager config:
https://docs.laminas.dev/laminas-servicemanager/configuring-the-service-manager/
Corresponding module manager feature config:
https://docs.laminas.dev/laminas-modulemanager/module-manager/
I suppose its worth mentioning that most if not all of the Feature interface methods map directly to a default pluginmanager implementation, ergo a specialized service manager.
I'm in windows using php-7.4.1 Architecture-x64, phalcon - 4.0.2, psr - 0.7.0 and follow instruction from 'https://docs.phalcon.io/4.0/en/application' but the problem is its always render frontend module & its view. I'm unable to find out what i'm doing wrong?
[Index.php]
use Phalcon\Mvc\Router;
use Phalcon\Mvc\Application;
use Phalcon\Di\FactoryDefault;
$di = new FactoryDefault();
$di->set('router',function () {
$router = new Router(false);
$router->setDefaultModule('frontend');
$router->add('/login',
[
'module' => 'backend',
'controller' => 'index',
'action' => 'index',
]
);
$router->add('/admin/products/:action',
[
'module' => 'backend',
'controller' => 'index',
'action' => 1,
]
);
return $router;
}
);
$application = new Application($di);
$application->registerModules(
[
'frontend' => [
'className' => \Multiple\Frontend\Module::class,
'path' => '../apps/frontend/Module.php',
],
'backend' => [
'className' => \Multiple\Backend\Module::class,
'path' => '../apps/backend/Module.php',
],
]
);
try {
$response = $application->handle($_SERVER["REQUEST_URI"]);
$response->send();
} catch (\Exception $e) {
echo $e->getMessage();
}
[Backend module]
<?php
namespace Multiple\Backend;
use Phalcon\Loader;
use Phalcon\Mvc\View;
use Phalcon\Di\DiInterface;
use Phalcon\Mvc\Dispatcher;
use Phalcon\Mvc\ModuleDefinitionInterface;
class Module implements ModuleDefinitionInterface
{
public function registerAutoloaders(DiInterface $di = null)
{
$loader = new Loader();
$loader->registerNamespaces(
[
'Multiple\Backend\Controllers' => '../apps/backend/controllers/',
'Multiple\Backend\Models' => '../apps/backend/models/',
]
);
$loader->register();
}
public function registerServices(DiInterface $di)
{
$di->set('dispatcher',function () {
$dispatcher = new Dispatcher();
$dispatcher->setDefaultNamespace('Multiple\Backend\Controllers');
return $dispatcher;
}
);
$di->set('view',function () {
$view = new View();
$view->setViewsDir('../apps/backend/views/');
return $view;
}
);
}
}
[Index Controller]
<?php
namespace Multiple\Backend\Controllers;
use Phalcon\Mvc\Controller;
class IndexController extends Controller
{
public function indexAction()
{
return '<h1>Back Controller!</h1>';
}
}
Did you set your namespaces in the frontend module as well? Like you did with registerAutoloaders in the backend.
Make sure you have registered your new module in
../app/bootstrap_web.php around line 47 which looks as shown below
$application->registerModules([
'frontend' => ['className' => 'MyApp\Modules\Frontend\Module'],
// <--- add your new module here --->
]);
and that your module class is also registered in the loader at ../app/config/loader.php around line 18 which looks as shown below
$loader->registerClasses([
'MyApp\Modules\Frontend\Module' => APP_PATH . '/modules/frontend/Module.php',
// <--- Add your new module class here --->
]);
Always keep an eye on your namespaces. I hope it helps.
I have create the chat application in laravel with Brodecast+Vue so when trying to my test broadcast class its getting error "BroadcastException in PusherBroadcaster.php (line 106)" I have double checked all configurations and api authentications are correct. but getting error and pusher debug console do not display and request.
driver :
'pusher' => [
'driver' => 'pusher',
'key' => env('PUSHER_APP_KEY'),
'secret' => env('PUSHER_APP_SECRET'),
'app_id' => env('PUSHER_APP_ID'),
'options' => [
'cluster' => 'ap1',
'encrypted' => true
],
],
event :
public $message;
public $user;
public function __construct($message, User $user)
{
$this->message = $message;
$this->user = $user;
}
test function :
public function test()
{
$user = User::find(Auth::id());
event(new ChatEvent('Hello pusher', $user));
return response('done');
}
i think you need to make encrypted = false.
'pusher' => [
'driver' => 'pusher',
'key' => env('PUSHER_APP_KEY'),
'secret' => env('PUSHER_APP_SECRET'),
'app_id' => env('PUSHER_APP_ID'),
'options' => [
'cluster' => 'ap1',
'encrypted' => false
],
],
I am having a trouble with login part.
I read this topic : http://www.yiiframework.com/wiki/771/rbac-super-simple-with-admin-and-user/ .
Then i follow its steps, but in step 6. it only configs for just one Controller. I have a Module called Admin with many controllers in it and i don't know how to apply this access control to the whole module. Can anyone help me ?
Sorry for my bad English.
You can create AdminController class, which will extends yii\web\Controller where you define your access rules in behaviors method and make other module controllers extend your AdminController and override behaviors method like this:
public function behaviors()
{
return \yii\helpers\ArrayHelper::merge(parent::behaviors(), [
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'delete' => ['post'],
],
],
]);
}
Here parent::behaviors() are behaviors from AdminController which define default access rules, and you merge them with specific behaviors in your child controller. It gives you flexibility to override some access rules if you need.
I can propose a variation of the method from the article that you mentioned.
Make first 2 steps as it was described and then do the following:
1. Add the field role to User model and evaluate it with thevalue of one of the constants from the article's example (User::ROLE_ADMIN or User::ROLE_USER)
2. Override the yii\web\User->can()
public function can($permissionName, $params = [], $allowCaching = true)
{
/** #var \app\models\User $user */
$user = $this->identity;
$access = false;
do {
if (\Yii::$app->user->isGuest) {
break;
}
if ($user->role === \common\models\User::ROLE_ADMIN) {
$access = true;
break;
}
if (is_array($permissionName)) {
$access = in_array($user->role, $permissionName);
} else {
$access = $permissionName === $user->role;
}
} while (false);
return $access;
}
So now you can check user's role like this:
\Yii::$app->user->can(User::ROLE_USER)
3. You say:
i don't know how to apply this access control to the whole module.
Then open your module class and add the following to the behaviors() method:
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'allow' => true,
'roles' => [User::ROLE_ADMIN]
]
]
]
];
}
In this example we grant access to ROLE_ADMIN to all actions of all controllers of your module.
That's it.
Make a custom model AccessRules.php as shown below:
<?php
namespace app\models;
class AccessRules extends \yii\filters\AccessRule
{
/**
* #inheritdoc
*/
protected function matchRole($user)
{
if (empty($this->roles)) {
return true;
}
foreach ($this->roles as $role) {
if ($role === '?') {
if ($user->getIsGuest()) {
return true;
}
} elseif ($role === '#') {
if (!$user->getIsGuest()) {
return true;
}
// Check if the user is logged in, and the roles match
} elseif (!$user->getIsGuest() && (int)$role === $user->identity->user_role) {
return true;
}
}
return false;
}
}
?>
Now open your site controller and add the following code in fuction behavior part:
use app\models\AccessRules;
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
// We will override the default rule config with the new AccessRule class
'ruleConfig' => [
'class' => AccessRules::className(),
],
'only' => ['create', 'update', 'delete','index'],
'rules' => [
[
'actions' => ['create', 'update', 'delete','index'],
'allow' => true,
// Allow admin to create
'roles' => [
'1'
],
]
],
],
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'logout' => ['post'],
],
],
];
}
According to The Yii2 Guide
"ACF is an action filter that can be used in a controller or a module" in the same way.
Just add below code in controller which you want to restrict functionality
'access' => [
'class' => AccessControl::className(),
'rules' =>
[
[
'actions' => ['index','view'],
'allow' => true,
'roles' => ['#']
],
[
'actions' => ['create','update','delete'],
'allow' => true,
'roles' => ['#'],
'matchCallback' => function ($rule, $action)
{
return Admin::isUserAdmin(Yii::$app->user->identity->username);
}
],
],
],
I have followed this solution in working with multiple models to upload using files using kartik fileinput during actionCreate.
My problem is achieving the same during actionUpdate, I keep on receiving the error below:
Either 'name', or 'model' and 'attribute' properties must be specified.
My form view is as follows:
echo $form->field($document,'document[]')->widget(FileInput::classname(), [
'options' => ['multiple' => true],
'pluginOptions' => [
// 'previewFileType' => 'any',
'showPreview' => false,
'showUpload' => false
], ]);
Whereas my controller actionUpdate is as follows
public function actionUpdate($id)
{
//$document = new EmployeeDocuments();
$model = $this->findModel($id);
$document = EmployeeDocuments::find()->indexBy('employee_id')->all();
$empavatar=$model->avatar;
$oldavatar=Yii::$app->session['oldavatar'] = $empavatar;
if ($model->load(Yii::$app->request->post()) ) {
// print_r($model); exit;
// $attachments = UploadedFile::getInstances($document, 'document');
// print_r($attachments); exit;
if($model->avatar==""){
$model->avatar=$oldavatar;
}
if ($model->save()){
if(!empty($attachments)){
foreach($attachments as $attachment):
$ext = end((explode(".", $attachment)));
$filename=end((explode(">", $attachment)));
$filename = ucwords(substr($filename, 0, strpos($filename, '.')));
// generate a unique file name
$file2save = Yii::$app->security->generateRandomString().".{$ext}";
$path=Yii::getAlias('#loc').'/uploads/employees/docs/'; //set directory path to save image
$attachment->saveAs($path.$model->id."_".$file2save); //saving img in folder
$attachment = $model->id."_".$file2save; //appending id to image name
\Yii::$app->db->createCommand()
->insert('lcm_hrm_employee_documents', ['document' => $attachment, 'name'=>$filename,'employee_id'=>$model->id])
->execute(); //manually update image name to db /* */
endforeach;
}
return $this->redirect(['view', 'id' => $model->id]);
}
else {
return $this->render('update', [
'model' => $model, 'document'=>$document
]);
}
} else {
return $this->render('update', [
'model' => $model, 'document'=>$document
]);
}
}
Change your form view to
echo $form->field($document,'document[]')->widget(FileInput::classname(), [
'options' => ['multiple' => true],
'attribute' =>'document[]',
'pluginOptions' => [
// 'previewFileType' => 'any',
'showPreview' => false,
'showUpload' => false
], ]);