I used a component name upload.php and save it in /app/controllers/components/ directory.
After that I used code in my controller like
<?php
App::uses('AppController', 'Controller');
App::uses('BarcodeHelper','Vendor');
/**
* OesUsers Controller
*
* #property OesUser $OesUser
*/
class OesUsersController extends AppController {
var $name = 'Images';
var $helpers = array('Html', 'Form');
var $components = array('upload');
function upload() {
if (empty($this->data)) {
$this->render();
} else {
$this->cleanUpFields();
// set the upload destination folder
$destination = realpath('../../app/webroot/img/uploads/') . '/';
// grab the file
$file = $this->data['Image']['filedata'];
// upload the image using the upload component
$result = $this->Upload->upload($file, $destination, null, array('type' => 'resizecrop', 'size' => array('400', '300'), 'output' => 'jpg'));
if (!$result){
$this->data['Image']['filedata'] = $this->Upload->result;
} else {
// display error
$errors = $this->Upload->errors;
// piece together errors
if(is_array($errors)){ $errors = implode("<br />",$errors); }
$this->Session->setFlash($errors);
$this->redirect('/images/upload');
exit();
}
if ($this->Image->save($this->data)) {
$this->Session->setFlash('Image has been added.');
$this->redirect('/images/index');
} else {
$this->Session->setFlash('Please correct errors below.');
unlink($destination.$this->Upload->result);
}
}
}
After save that I find error that is missing component. I could not find any mistake.Can any body help me?
You have placed the component in the wrong folder. In CakePHP 2.x, components are placed in app/Controller/Component. You also have to rename the component from upload.php to UploadComponent (and probably adapt the code to make it work with CakePHP 2.x).
Related
I want to use https://www.verot.net/php_class_upload_download.htm library in my project for resizing images. However, when I submit form it gives this error
I have loaded the library in the autoloader and I renamed library to "my_upload" and gave the same class name.
However, I do not know why this error occurs.
And here is my controller:
<?php
class Blog extends CI_Controller{
function __construct() {
parent::__construct();
}
public function add() {
if(!$this->session->userdata('logged_in')) {
$this->session->set_flashdata('not_loggedin','<div class="alert alert-success text-center">Please Login</div>');
redirect('login');
}
$data['title'] = 'Ədd nyus';
$data['author'] = $this->Blog_model->get_author();
$data['category'] = $this->Blog_model->get_category();
$this->load->view('templates/header');
$this->load->view('blog/add', $data);
$this->load->view('templates/footer');
}
public function create() {
if(!$this->session->userdata('logged_in')) {
$this->session->set_flashdata('not_loggedin','<div class="alert alert-success text-center">Please Login</div>');
redirect('login');
}
//insert image
$now = date("YmdHis");
$this->my_upload->upload($_FILES["userfile"]);
if ( $this->my_upload->uploaded == true ) {
$this->my_upload->allowed = array('jpg|png');
$this->my_upload->file_new_name_body = 'image_resized' . $now;
$this->my_upload->image_resize = true;
$this->my_upload->image_ratio_fill = true;
$this->my_upload->image_x = 360;
$this->my_upload->image_y = 236;
// $this->my_upload->image_ratio_y = true;
$this->my_upload->process('C:\xampp\htdocs\edu-center\assets\img\blog');
if ( $this->my_upload->processed == true ) {
$this->my_upload->clean();
$post_image = $_FILES["userfile"]["name"];
}
} else {
$post_image = '';
}
//insert the user registration details into database
$randnum = mt_rand(100000,999999);
$slugtitle = mb_strtolower($this->input->post('title_az'), 'UTF-8') . '-' .$randnum;
$slug = url_title($slugtitle);
$post_image = str_replace(' ', '_', $post_image);
$post_image = preg_replace('/_+/', '_', $post_image);
date_default_timezone_set('Asia/Baku');
$data = array(
'title_az' => strip_tags($this->input->post('title_az')),
'title_rus' => strip_tags($this->input->post('title_rus')),
'author_id' => $this->input->post('author_id'),
'category_id' => strip_tags($this->input->post('category')),
'body_az' => $this->input->post('body_az'),
'body_rus' => $this->input->post('body_rus'),
'date' => date("d-m-Y"),
'news_slug' => $slug,
'img' => $post_image
);
$this->Blog_model->add_news($data);
$this->session->set_flashdata('changed_msg','<div class="alert alert-success text-center">Ваши изменения были сохранены!</div>');
redirect('blog');
}
Where can be the problem?
imho the best way is to create a third party library for that
copy your class into your folder application/third_party/upload/
and in your controller you simply inlcude this file like:
require_once(APPPATH."third_party/upload/my_upload.php");
$objUpload = new my_upload($_FILES);
If you really want a library for that try the following:
The problem is your library gets instantiated by CI - you don't really have control over the constructor
the only way you could do is to include a "wrapper" library
e.g.
<?php
require_once(APPPATH."libraries/my_upload.php");
class Uploadwrapper_library
{
public function get($files)
{
return new my_upload($files);
}
}
in your controller you could do
$this->load->library("uploadwrapper_library");
$objMyUpload = $this->uploadwrapper_library->get($_FILES);
Well if you look at the file - system/libraries/Upload.php it's constructor requires a parameter...
public function __construct($config = array())
So with your MY_Upload class which is CI's way to allow you to override core classes, you need to follow suit with the class you are extending.
You've not shown your constructor so I don't know what you have attempted with your constructor...
I am using Zend 1.12
I have a form which has two fields: email, and file
My index view shows the form. And after validation is successful, I want to parse the csv file and show the content on result view:
My Code:
IndexController:
class IndexController extends Zend_Controller_Action {
public function init() {
/* Initialize action controller here */
}
public function indexAction() {
// action body
$form = new Application_Form_FileUpload();
$form->submit->setLabel('Upload');
$this->view->form = $form;
if ($this->getRequest()->isPost()) {
$formData = $this->getRequest()->getPost();
if ($form->isValid($formData)) {
$file = $form->getValue('file');
$email = $form->getValue('email');
//$this->_helper->viewRenderer('result', null, true);
//$this->_helper->redirector('result', 'index','', array('email' => $email, 'file' => $file));
$this->_helper->redirector->gotoRouteAndExit (array(
'controller' => 'index',
'action' =>'result',
'name' => $file));
} else {
$form->populate($formData);
}
}
}
public function resultAction() {
$email = $this->_getParam('name');
$this->view->email = $email;
}
}
My index view:
<?php
$this->form->setAction($this->url(array('action' => 'index')));
echo $this->form;
?>
My result view:
<?php
echo $this->email;
//echo the content of the csv file;
?>
My result view is empty always.
What is the correct/right way to get the form data, and if validation is successful, show the content in result view.
Edit: I have succeeded to get parameters passed to resultaction.
I just was looking into different file. That is why it was not showing up.
But still, is it the right way to do it for my case? For it seems not correct.
I want to create one controller file which is creating automatically a function if i create a menu dynamically and also want to create view page which is connencted to this main controller.. how to do that?
Current code:
public function our_history()
{
$data['category']= $this->menu_model->getCategory('$lang');
$data['subcategory']= $this->menu_model->getSubCategory('$lang');
$this->load->view('vwMain',$data);//Left Menu }
}
Follow below steps Hope that makes sense.
-- Admin section --
/*content.php -- controller starts here */
class Content extends VCI_Controller {
# Class constructor
function __construct()
{
parent::__construct();
$this->load->model('content_model');
}
/*
Add page logic
*/
function edit_page($id = null)
{
$this->_vci_layout('your_layoutname');
$this->load->library('form_validation');
$view_data = array();
//Set the view caption
$view_data['caption'] = "Edit Content";
//Set the validation rules for server side validation
// rule name editcontent should be defined
if($this->form_validation->run('editcontent')) {
//Everything is ok lets update the page data
if($this->content_model->update(trim($id))) {
$this->session->set_flashdata('success', "<li>Page has been edited successfully.</li>");
$this->output->set_header('location:' . base_url() . 'content/manage_content');
} else {
$this->session->set_flashdata('error', "<li>Unknown Error: Unable to edit page.</li>");
$this->output->set_header('location:' . base_url() . 'content/manage_content');
}
} else {
$page = $this->content_model->get_content_page(trim($id));
$view_data["id"] = $page->id;
$view_data["page_title"] = $page->page_title;
$view_data["page_menu_slug"] = $page->page_menu_slug;
$view_data["page_name"] = $page->page_name;
$view_data["page_content"] = $page->page_content;
$view_data["status"] = $page->status;
$this->_vci_view('content_editpage', $view_data);
}
}
/*
Edit page logic
*/
function add_page()
{
$this->_vci_layout('your_layoutname');
$this->load->library('form_validation');
$view_data = array();
$view_data['caption'] = "Edit Content";
if($this->form_validation->run('editcontent')) {
// after passing validation rule data to be saved
// editcontent rule must be defined in formvalidations file
//Everything is ok lets update the page data
if($this->content_model->add()) {
$this->session->set_flashdata('success', "<li>Page has been edited successfully.</li>");
$this->output->set_header('location:' . base_url() . 'content/manage_content');
} else {
$this->session->set_flashdata('error', "<li>Unknown Error: Unable to edit page.</li>");
$this->output->set_header('location:' . base_url() . 'content/manage_content');
}
} else {
$page = $this->content_model->get_content_page(trim($id));
$view_data["id"] = $page->id;
$view_data["page_title"] = $page->page_title;
$view_data["page_menu_slug"] = $page->page_menu_slug;
$view_data["page_name"] = $page->page_name;
$view_data["page_content"] = $page->page_content;
$view_data["status"] = $page->status;
$this->_vci_view('content_editpage', $view_data);
}
}
}
/**
* content.php -- controller ends here
*/
/*
Content_model starts here
*/
class Content_model extends CI_Model {
// update logic goes here
function update($id = null) {
if(is_null($id)) {
return false;
}
$data = array(
'page_title' => htmlspecialchars($this->input->post('page_title',true)),
'page_name' => htmlspecialchars($this->input->post('page_name',true)),
'page_content' => $this->input->post('page_content',true),
'page_menu_slug' => htmlspecialchars($this->input->post('page_menu_slug',true)),
'status' => htmlspecialchars($this->input->post('status',true))
);
$this->db->where('id', $id);
$this->db->update('content', $data);
return true;
}
// Add logic goes here
function add() {
$data = array(
'page_title' => htmlspecialchars($this->input->post('page_title',true)),
'page_name' => htmlspecialchars($this->input->post('page_name',true)),
'page_content' => $this->input->post('page_content',true),
'page_menu_slug' => htmlspecialchars($this->input->post('page_menu_slug',true)),
'status' => htmlspecialchars($this->input->post('status',true))
);
$this->db->where('id', $id);
$this->db->insert('content', $data);
return true ;
}
}
/*
Content_model ends here # Admin section changes ends here
*/
-- Add view files also to admin section content_editpage.php
Now go to your routes.php file for front section --
add below line at last --
$route['(:any)'] = 'page/view_usingslug/$1';
This will be for all urls like --- http://yourdomainname/your_slug_name
// create again a controller in front section page.php --
class page extends VCI_Controller {
function __construct()
{
parent::__construct();
}
function view_usingslug($slug='')
{
// retrieve the data by slug from content table using any model class and assign result to $view_dat
$this->_vci_view('page',$view_data);
//page.php will be your view file
}
}
Suppose Your URL is
www.example.com/controllername/methodname/menutitle1
or
www.example.com/controllername/methodname/menutitle2
So this is how you handle these pages.
public function method()
{
$menutitle = $this->uri->segment(3);
$query = $this->db->get_where('TableName',array('Menutitle'=>$menutitle))
$data['content'] = $query->row()->page_content;
$this->load->view('common_page',$data);
}
I want to upload images in my cakephp 3.0 app. But I get the error message:
Notice (8): Undefined index: Images [APP/Controller/ImagesController.php, line 55]
Are there already some examples for uploading files (multiple files at once) in cakePHP 3.0? Because I can only find examples for cakePHP 2.x !
I think I need to add a custom validation method in my ImagesTable.php? But I can't get it to work.
ImagesTable
public function initialize(array $config) {
$validator
->requirePresence('image_path', 'create')
->notEmpty('image_path')
->add('processImageUpload', 'custom', [
'rule' => 'processImageUpload'
])
}
public function processImageUpload($check = array()) {
if(!is_uploaded_file($check['image_path']['tmp_name'])){
return FALSE;
}
if (!move_uploaded_file($check['image_path']['tmp_name'], WWW_ROOT . 'img' . DS . 'images' . DS . $check['image_path']['name'])){
return FALSE;
}
$this->data[$this->alias]['image_path'] = 'images' . DS . $check['image_path']['name'];
return TRUE;
}
ImagesController
public function add()
{
$image = $this->Images->newEntity();
if ($this->request->is('post')) {
$image = $this->Images->patchEntity($image, $this->request->data);
$data = $this->request->data['Images'];
//var_dump($this->request->data);
if(!$data['image_path']['name']){
unset($data['image_path']);
}
// var_dump($this->request->data);
if ($this->Images->save($image)) {
$this->Flash->success('The image has been saved.');
return $this->redirect(['action' => 'index']);
} else {
$this->Flash->error('The image could not be saved. Please, try again.');
}
}
$images = $this->Images->Images->find('list', ['limit' => 200]);
$projects = $this->Images->Projects->find('list', ['limit' => 200]);
$this->set(compact('image', 'images', 'projects'));
$this->set('_serialize', ['image']);
}
Image add.ctp
<?php
echo $this->Form->input('image_path', [
'label' => 'Image',
'type' => 'file'
]
);
?>
Image Entity
protected $_accessible = [
'image_path' => true,
];
In your view file, add like this, in my case Users/dashboard.ctp
<div class="ChImg">
<?php
echo $this->Form->create($particularRecord, ['enctype' => 'multipart/form-data']);
echo $this->Form->input('upload', ['type' => 'file']);
echo $this->Form->button('Update Details', ['class' => 'btn btn-lg btn-success1 btn-block padding-t-b-15']);
echo $this->Form->end();
?>
</div>
In your controller add like this, In my case UsersController
if (!empty($this->request->data)) {
if (!empty($this->request->data['upload']['name'])) {
$file = $this->request->data['upload']; //put the data into a var for easy use
$ext = substr(strtolower(strrchr($file['name'], '.')), 1); //get the extension
$arr_ext = array('jpg', 'jpeg', 'gif'); //set allowed extensions
$setNewFileName = time() . "_" . rand(000000, 999999);
//only process if the extension is valid
if (in_array($ext, $arr_ext)) {
//do the actual uploading of the file. First arg is the tmp name, second arg is
//where we are putting it
move_uploaded_file($file['tmp_name'], WWW_ROOT . '/upload/avatar/' . $setNewFileName . '.' . $ext);
//prepare the filename for database entry
$imageFileName = $setNewFileName . '.' . $ext;
}
}
$getFormvalue = $this->Users->patchEntity($particularRecord, $this->request->data);
if (!empty($this->request->data['upload']['name'])) {
$getFormvalue->avatar = $imageFileName;
}
if ($this->Users->save($getFormvalue)) {
$this->Flash->success('Your profile has been sucessfully updated.');
return $this->redirect(['controller' => 'Users', 'action' => 'dashboard']);
} else {
$this->Flash->error('Records not be saved. Please, try again.');
}
}
Before using this, create a folder in webroot named upload/avatar.
Note: The input('Name Here'), is used in
$this->request->data['upload']['name']
you can print it if you want to see the array result.
Its works like a charm in CakePHP 3.x
Now that everyone makes advertisement for his plugins here, let me do this as well. I've checked the Uploadable behavior linked in the other question, it's pretty simple and half done it seems.
If you want a complete solution that is made to scale on enterprise level check FileStorage out. It has some features I haven't seen in any other implementations yet like taking care of ensuring your won't run into file system limitations in the case you get really many files. It works together with Imagine to process the images. You can use each alone or in combination, this follows SoC.
It is completely event based, you can change everything by implementing your own event listeners. It will require some intermediate level of experience with CakePHP.
There is a quick start guide to see how easy it is to implement it. The following code is taken from it, it's a complete example, please see the quick start guide, it's more detailed.
class Products extends Table {
public function initialize() {
parent::initialize();
$this->hasMany('Images', [
'className' => 'ProductImages',
'foreignKey' => 'foreign_key',
'conditions' => [
'Documents.model' => 'ProductImage'
]
]);
$this->hasMany('Documents', [
'className' => 'FileStorage.FileStorage',
'foreignKey' => 'foreign_key',
'conditions' => [
'Documents.model' => 'ProductDocument'
]
]);
}
}
class ProductsController extends ApController {
// Upload an image
public function upload($productId = null) {
if (!$this->request->is('get')) {
if ($this->Products->Images->upload($productId, $this->request->data)) {
$this->Session->set(__('Upload successful!');
}
}
}
}
class ProductImagesTable extends ImageStorageTable {
public function uploadImage($productId, $data) {
$data['adapter'] = 'Local';
$data['model'] = 'ProductImage',
$data['foreign_key'] = $productId;
$entity = $this->newEntity($data);
return $this->save($data);
}
public function uploadDocument($productId, $data) {
$data['adapter'] = 'Local';
$data['model'] = 'ProductDocument',
$data['foreign_key'] = $productId;
$entity = $this->newEntity($data);
return $this->save($data);
}
}
Maybe the following would help. It's a behavior who helps you to upload files very easy!
http://cakemanager.org/docs/utils/1.0/behaviors/uploadable/
Let me know if you struggle.
Greetz
/*Path to Images folder*/
$dir = WWW_ROOT . 'img' .DS. 'thumbnail';
/*Explode the name and ext*/
$f = explode('.',$data['image']['name']);
$ext = '.'.end($f);
/*Generate a Name in my case i use ID & slug*/
$filename = strtolower($id."-".$slug);
/*Associate the name to the extension */
$image = $filename.$ext;
/*Initialize you object and update you table in my case videos*/
$Videos->image = $image;
if ($this->Videos->save($Videos)) {
/*Save image in the thumbnail folders and replace if exist */
move_uploaded_file($data['image']['tmp_name'],$dir.DS.$filename.'_o'.$ext);
unlink($dir.DS.$filename.'_o'.$ext);
}
<?php
namespace App\Controller\Component;
use Cake\Controller\Component;
use Cake\Controller\ComponentRegistry;
use Cake\Network\Exception\InternalErrorException;
use Cake\Utility\Text;
/**
* Upload component
*/
class UploadRegCompanyComponent extends Component
{
public $max_files = 1;
public function send( $data )
{
if ( !empty( $data ) )
{
if ( count( $data ) > $this->max_files )
{
throw new InternalErrorException("Error Processing Request. Max number files accepted is {$this->max_files}", 1);
}
foreach ($data as $file)
{
$filename = $file['name'];
$file_tmp_name = $file['tmp_name'];
$dir = WWW_ROOT.'img'.DS.'uploads/reg_companies';
$allowed = array('png', 'jpg', 'jpeg');
if ( !in_array( substr( strrchr( $filename , '.') , 1 ) , $allowed) )
{
throw new InternalErrorException("Error Processing Request.", 1);
}
elseif( is_uploaded_file( $file_tmp_name ) )
{
move_uploaded_file($file_tmp_name, $dir.DS.Text::uuid().'-'.$filename);
}
}
}
}
}
We're using https://github.com/josegonzalez/cakephp-upload with great success in our production app, and has done so for quite some time.
Has awesome support for using "Flysystem" (https://flysystem.thephpleague.com/) as well - which is abstractions from specific file system(s) - so moving from normal local file system to S3 is a no-brainer, or Dropbox or whatever place you want :-)
You can find related (high quality) plugins on file uploading right here: https://github.com/FriendsOfCake/awesome-cakephp#files - I've used "Proffer" with success as well, and it's by no means "almost done" or anything alike - both has all my recommendations and is in my eyes production ready!
It's come to my attention that my image processing code that I currently have in my controller would be better suited in a model, but I'm not sure even where to start to do this.
I have a controller that handles uploading an image, renaming the file and storing it in the database using Doctrine:
<?php
class Addimage extends Controller
{
function index()
{
$vars['content_view'] = 'uploadimage';
$this->load->view('template', $vars);
}
public function do_upload()
{
$this->load->library('form_validation');
if($this->_submit_validate() == FALSE)
{
/*THIS CODE BLOCK IS DUPLICATED FROM MY HOME PAGE CONTROLLER - this is one of the reasons I want to refactor.*/
$vars['recentimages'] = Doctrine_Query::create()
->select('photo_path')
->from('Gif g')
->orderBy('g.created_at DESC')
->limit(12)
->execute();
$vars['title'] = 'Home';
$vars['content_view'] = 'welcome_message';
$this->load->view('template_front', $vars);
}
else
{
$basedir = $this->config->item('server_root') . $this->config->item('upload_dir');
//If the directory doesn't already exist, create it.
if (!is_dir($basedir))
{
mkdir($basedir, 0777);
}
$config = array(
'allowed_types' => "gif",
'upload_path' => $basedir,
'remove_spaces' => true
);
$this->load->library('upload', $config);
if(!$this->upload->do_upload())
{
$data['error'] = 'There was a problem with the upload';
}
else
{
$image_data = $this->upload->data();
$fileName = $image_data['file_name'];
$title = $this->input->post('title');
//Rename File based on how many of that letter
//are already in the database
$imageCount = Doctrine_Query::create()
->select('COUNT(i.id) as num_images')
->from('Gif i')
->execute();
$imageCount = $imageCount[0]->num_images++;
//Rename file based on title and number of images in db.
$newFileName = preg_replace('/[^a-zA-Z0-9\s]/', '', $title) . '_' . $imageCount . $image_data['file_ext'];
rename($basedir . $fileName, $basedir . $newFileName);
$gif = new Gif();
$gif->photo_path = $newFileName;
$gif->title = $title;
if(Current_User::user())
{
$gif->User = Current_User::user();
}
else
{
$gif->User = Doctrine::getTable('User')->findOneById($this->config->item('anonuid'));
}
$gif->save();
}
redirect('/', 'location');
}
}
private function _submit_validate()
{
$this->form_validation->set_rules('title', 'Title', 'required');
return $this->form_validation->run();
}
}
I would like to be able to have most of this in a model, because I'm using a template system for the views where my uploadimage.php view is just the upload form so that it can be dropped on any page. Also, I only have experience using Doctrine models.
Thanks for any help in advance
I had a very similar issue on my own project: duplication in the controllers. I think in your case it makes sense to only move parts of that logic into the model, because most of it actually makes sense to be in a controller.
Rendering view definitely should be in a controller, and input validation as well. I would move the transactional part to the model: the SQL, file handling and image manipulation.
You will then still have some duplication but I see no other way since controller logic and model logic are so interwoven in this case.