CakePHP 3: Export to excel files - cakephp

I'm new to CakePHP, I'm using version 3.0, and have asked before how to export to Excel using PHPExcel. I have downloaded and installed it in the vendor folder and created the different files as follows:
controller
<?php
namespace App\Controller;
use App\Controller\AppController;
/**
* Tests Controller
*
* #property \App\Model\Table\TestsTable $Tests
*/
class TestsController extends AppController
{
var $helpers = array('Html', 'Form','Csv','PHPExcel');
public function exportoexcel()
{
$this->set('data',$this->Tests->find('all'));
$this->response->download("export.xls");
}
}
src/template/.ctp
<?php
$this->PhpExcel->createWorksheet()
->setDefaultFont('Calibri', 12);
// define table cells
$table = array(
array('label' => __('User'), 'filter' => true),
array('label' => __('Type'), 'filter' => true),
array('label' => __('Date')),
array('label' => __('Description'), 'width' => 50, 'wrap' => true),
array('label' => __('Modified'))
);
// add heading with different font and bold text
$this->PhpExcel->addTableHeader($table, array('name' => 'Cambria', 'bold' => true));
// add data
foreach ($data as $d) {
$this->PhpExcel->addTableRow(array(
));
}
// close table and output
$this->PhpExcel->addTableFooter()
->output();
?>
In the src/view/helper folder I have created the phpexcel.php and phpexcelhelper file .
Then when I run the application I always get this error:
require(C:\wamp\www\qualite2\qualite\src\View\Helper\PHPExcel\Autoloader.php): failed to open stream: No such file or directory [APP/View\Helper\PHPExcel.php, line 32]
Code Context
if (!defined('PHPEXCEL_ROOT')) {
define('PHPEXCEL_ROOT', dirname(__FILE__) );
require(PHPEXCEL_ROOT . '\PHPExcel\Autoloader.php');

Related

CakePHP 3 Model Form Send Email with User submitted attachment

These are the results from when I do debug($this->request->data)
I ommited the fields that didn't matter
I get this
[
'file' => 'Atest.doc'
]
I want this
[
'file' => [
'tmp_name' => '/Applications/MAMP/tmp/php/phpgBEFye',
'error' => (int) 0,
'name' => 'Atest.doc',
'type' => 'application/msword',
'size' => (int) 45056
]
Here is .ctp
echo $this->Form->create($contact, ['id'=>'contact-form']);
echo $this->Form->file('file', ['label'=> 'Cover Letter']);
echo $this->Form->button('Send');
echo $this->Form->end();
My Contact Controller
<?php
namespace App\Controller;
use App\Controller\AppController;
use App\Form\ContactForm;
use Cake\ORM\TableRegistry;
use Cake\Mailer\Email;
use Cake\Network\Exception\SocketException;
use Burzum\FileStorage\Storage\StorageManager;
public function index($option = 'index'){
$contact = new ContactForm();
if ($this->request->is('post')) {
if ($contact->execute($this->request->getData())) {
//debug($this->request->getData() );
}
}
///..I omitted the rest
}
echo $this->Form->create($document, ['enctype' => 'multipart/form-data']);

Can't submit form using create();

So i have this method inside of my:
JobsController.ctp:
<?php
namespace App\Controller;
use App\Controller\AppController;
use Cake\ORM\TableRegistry;
/**
* Jobs Controller
*
* #property \App\Model\Table\JobsTable $Jobs
*/
class JobsController extends AppController
{
public $name = 'Jobs';
public function add()
{
//Some Vars assigning skipped, var job is empty
$this->set('job','Job');
$this->Job->create();
}
}
And I have this view with the form itself:
add.ctp:
<?= $this->Form->create($job); ?>
<fieldset>
<legend><?= __('Add Job Listing'); ?></legend>
<?php
echo $this->Form->input('title');
echo $this->Form->input('company_name');
echo $this->Form->input('category_id',array(
'type' => 'select',
'options' => $categories,
'empty' => 'Select Category'
));
echo $this->Form->input('type_id',array(
'type' => 'select',
'options' => $types,
'empty' => 'Select Type'
));
echo $this->Form->input('description', array('type' => 'textarea'));
echo $this->Form->input('city');
echo $this->Form->input('contact_email');
?>
</fieldset>
<?php
echo $this->Form->button('Add');
$this->Form->end();
?>
Also this table class:
JobsTable.php
<?php
namespace App\Model\Table;
use Cake\ORM\Table;
class JobsTable extends Table
{
public function initialize(array $config)
{
$this->belongsTo('Types', [
'foreignKey' => 'type_id',
'joinType' => 'INNER',
]);
$this->belongsTo('Categories', [
'foreignKey' => 'category_id',
'joinType' => 'INNER',
]);
}
}
And when I submit it, it gives me next error:
Error: Call to a member function create() on boolean
No idea how to fix.
I also have an entity
Job.php:
<?php
namespace App\Model\Entity;
use Cake\ORM\Entity;
/**
* Job Entity.
*/
class Job extends Entity
{
/**
* Fields that can be mass assigned using newEntity() or patchEntity().
*
* #var array
*/
protected $_accessible = array(
'category_id' => true,
'user_id' => true,
'type_id' => true,
'company_name' => true,
'title' => true,
'description' => true,
'city' => true,
'contact_email' => true,
'category' => true,
'user' => true,
'type' => true,
);
}
So how do I fix this error, that appears on form submit?
Error: Call to a member function create() on boolean
I guess I need to do something with $this->set('job'); ? but I'm not sure what exactly
By convention the default, auto-loadable table for a controller is based on the controller name without the trailing Controller, so for JobsController a table class named Jobs(Table) can be autoloaded.
In case the table class cannot be loaded (for example because it doesn't exist, or because the name doesn't match the one derived from the controller name), the magic getter that handles this will return false, a boolean, and this is where you are trying to call a method on, hence the error.
create() btw doesn't exist anymore, you should have a look at the ORM migration guide, and the docs in general to get a grasp on how things now work.
So either use $this->Jobs and make sure that you have a table class named JobsTable, or override the default model to use (Controller::_setModelClass()), or load the desired table manually (TableRegistry::get() or Controller::loadModel()).
See also
Cookbook > Database Access & ORM
Cookbook > Controllers > Loading Additional Models

Form validation not working properly in cakePHP 2.4.6

In version 2.2.1 I could validate a form using rules and custom messages like below. But somehow the password rule isn't working as of version 2.3. Any help what I might be doing wrong here?
Model:
class User extends AppModel {
public $validate = array(
'password' => array(
'rule' => array ('between', 5, 10 ),
'message' => 'Password must between 5 and 10 characters long'
)
);
public function beforeSave($options = array()) {
$this->data['User']['password'] = Security::hash($this->data['User']['password'], 'sha1', true);
return true;
}
}
View:
<?php
echo $this->Form->create();
echo $this->Form->input('firstname', array('label' => 'First name'));
echo $this->Form->input('lastname', array('label' => 'Last name'));
echo $this->Form->input('adminrole', array('type' => 'checkbox', 'label' => 'Is admin?<br /><br />'));
echo $this->Form->input('email', array('label' => 'E-mail address'));
echo $this->Form->input('password', array('label' => 'Password'));
echo $this->Form->input('picturethumb', array('type' => 'file', 'label' => 'Profile picture'));
echo $this->Form->end('Save');
?>
Please bare in mind that this exact same code validates correctly in 2.2.1
Controller:
class UsersController extends AppController {
public function index() {
$users = $this->User->find('all');
$this->set('users', $users);
}
public function add() {
if ($this->request->is('post')) {
$this->User->save($this->request->data);
$this->redirect('/users');
}
}
}
Try this-
public function add() {
if ($this->request->is('post')) {
$this->User->create();
if($this->User->save($this->request->data)){
$this->redirect('/users');
}else{
$this->Session->setFlash('Opps... Something is wrong');
}
}
}
I don't work with cake sometime, but I remember had this problem before. The problem is, the cakephp will create a hash of password, so when Model get password is already big. What I did in time was make another validate, like password_tmp and use it like field and create the hash by myself in controller for the real field password.

View file is missing when outputting CSV

I'm using CakePHP 2.x, and running it locally on IIS. I'm following the tutorial on Exporting data to CSV the CakePHP way, and I'm getting an error.
The URL I'm entering is like: http://myproject.localhost/territory/spreadsheet.csv
I have Router::parseExtensions('csv'); as the first thing in app\Config\routes.php
Here's my controller:
`class TerritoryController extends AppController
{
public $useTable = 'ezrep_territory';
public $paginate = array('limit' => 50);
public function beforeFilter()
{
parent::beforeFilter();
$this->Auth->deny('index');
}
public function Index()
{
// ... snip ...
}
public function Spreadsheet()
{
$data = $this->Territory->find(
'all',
array(
'conditions' => array('Territory.ez' => $this->ez),
'fields' => array('territory','terrcode','terrdesc'),
'contain' => false
));
$headers = array(
'Territory'=>array(
'territory' => 'Territory ID',
'terrcode' => 'Terr Code',
'terrdesc' => 'Terr Desc'
)
);
array_unshift($data,$headers);
$this->set(compact('data'));
}
}
`
In app\View\Layouts\csv, I have a file default.ctp:
<?php
echo $content_for_layout;
?>
And in app\View\Territory, I have a file spreadsheet.ctp:
// Loop through the data array
foreach ($data as $row)
{
// Loop through every value in a row
foreach ($row['Territory'] as &$value)
{
// Apply opening and closing text delimiters to every value
$value = "\"".$value."\"";
}
// Echo all values in a row comma separated
echo implode(",",$row['Territory'])."\n";
}
When I go to http://myproject.localhost/territory/spreadsheet.csv, I get a page that appears to be rendered through the app\View\Layouts\default.ctp with an error:
View file "C:\zproj\ezrep40\app\View\Territory\csv\spreadsheet.ctp" is missing.
and
Error: An Internal Error Has Occurred.
What am I doing wrong?
This is not right
And in app\View\Territory, I have a file spreadsheet.ctp:
you'll need to place also the view, and not just the layout, in a sub directory named after the extension:
app\View\Territory\csv\spreadsheet.ctp

Lithium: how do I display related data in forms and then save them?

I'm using Lithium with MySQL.
I have a Users model that hasOne Contacts.
The Contacts model belongsTo Users.
I've listed a very basic version of my code, below.
My questions:
When I edit a user and submit the form, how do I make Users::edit save the Contact data, as well?
Also, how do I display contacts.email in the Users edit view?
models/Users.php
<?php
namespace app\models;
class Users extends \lithium\data\Model {
public $hasOne = array('Contacts');
protected $_schema = array(
'id' => array('type' => 'integer',
'key' => 'primary'),
'name' => array('type' => 'varchar')
);
}
?>
models/Contacts.php
<?php
namespace app\models;
class Contacts extends \lithium\data\Model {
public $belongsTo = array('Users');
protected $_meta = array(
'key' => 'user_id',
);
protected $_schema = array(
'user_id' => array('type' => 'integer',
'key' => 'primary'),
'email' => array('type' => 'string')
);
}
?>
controllers/UsersController.php
<?php
namespace app\controllers;
use app\models\Users;
class UsersController extends \lithium\action\Controller {
public function edit() {
$user = Users::find('first', array(
'conditions' => array('id' => $this->request->id),
'with' => array('Contacts')
)
);
if (!empty($this->request->data)) {
if ($user->save($this->request->data)) {
//flash success message goes here
return $this->redirect(array('Users::view', 'args' => array($user->id)));
} else {
//flash failure message goes here
}
}
return compact('user');
}
}
?>
views/users/edit.html.php
<?php $this->title('Editing User'); ?>
<h2>Editing User</h2>
<?= $this->form->create($user); ?>
<?= $this->form->field('name'); ?>
<?= $this->form->field('email', array('type' => 'email')); ?>
<?= $this->form->end(); ?>
Not many people know this but with lithium you can bind a form to multiple objects.
In your controller, return both a user and a contact object. Then in your form:
<?= $this->form->create(compact('user', 'contact')); ?>
You then render a field form a specific object like this:
<?= $this->form->field('user.name'); ?>
<?= $this->form->field('contact.email'); ?>
When the user submits the form, the data for both objects will be stored as:
$this->request->data['user'];
$this->request->data['contact'];
You can use this information to update the database as you would normally. If you only want to save the information if data from both objects are valid, you can call validate like this:
$user = Users::create($this->request->data['user']);
if($user->validates()) {
$userValid = true;
}
$contact = Contacts::create($this->request->data['contact']);
if($contact->validates()) {
$contactValid = true;
}
if($userValid && $userValid){
// save both objects
}
Hope that helps :)

Resources