use of upload class in codeigniter - Model or Controller? - file

Quick question about CI.
I have a view with a form, several text input fields and a file upload.
I want to be able to take the input from the text fields, save it to the DB, and then upload the image.
I've achieved this by having the upload code in a controller, and if the upload is successful, a call to my Model is made to update the database.
Is this "best practice", or indeed an acceptable way of doing it? Or should the File Upload go in the Model. Does it matter?
Essentially my code is:
function edit_category()
{
$config['upload_path'] = 'images/category/';
$config['allowed_types'] = 'gif|jpg|jpeg|png';
$config['max_size'] = '1000';
$config['max_width'] = '300';
$config['max_height'] = '300';
$this->load->library('upload', $config);
if(!$this->upload->do_upload())
{
$this->session->set_flashdata('status', $this->upload->display_errors());
redirect('admin/category/edit/'.$this->input->post('catID'), 'location');
}
else /*no errors, upload is successful..*/
{
$fInfo = $this->upload->data();
//$this->_createThumbnail($fInfo['file_name']);
//process form POST data.
$data = array(
'catName' => $this->input->post('catName'),
'catDesc' => $this->input->post('catDesc'),
'catImage' => $fInfo['file_name']
);
/* update the database */
$category = $this->category_model->edit_category($data, $this->input->post('catID'));

I would put this in a model because I like to keep my controllers as slim as possible. I think of the controller as the link between the views and the back-room processing, not the processing itself.
I'm not sure if this is "best practise" or not. It will certainly work the way you're doing it too. CodeIgniter allows you to be quite flexible in how you apply mvc theory.

Use your models to interact with data whether it's a database interaction, an api call, or a file upload and download. Use your controller to run the show and make calls to that data. Do your best to keep them all separate in case the method for interacting with that data ever changes. Most of the time we think of the model as a database function, but it really should be ANY data no matter how it's retrieved.

I came out with this same dilemma, should I put the file upload functionality in controller or model.
After few trial and error I decided to put it under model for reusable purposes as calling controller from another controller is against the MVC concept.

Related

laravel angularjs update multiple rows

i have a sortable table and after successfully moving an item i want to update all the rows in the databasetable which are effected from sorting.
my problem is that i dont know what's the best way to update multiple rows in my database with eloquent and how to send the data correct with angularjs
in angularjs i did this
//creating the array which i want to send to the server
var update = [];
for (min; min <= max; min++){
...
var item = {"id": id, "position": position};
update.push(item);
...
}
//it doesn't work because its now a string ...
var promise = $http.put("/api/album/category/"+update);
//yeah i can read update in my controller in laraval, but i need the fakeid, because without
//i get an error back from laravel...
var promise = $http.put("/api/album/category/fakeid", update);
in laravel i have this, but is there an possibility to update the table with one call instead of looping
//my route
Route::resource('/api/album/category','CategoryController');
//controller
class CategoryController extends BaseController {
public function update()
{
$updates = Input::all();
for($i = 0; $i<count($updates); $i++){
Category::where('id','=', $updates[$i]["id"])
->update(array('position' => $updates[$i]["position"]));
}
}
}
and yes this works but i think there are better ways to solve the put request with the fakeid and the loop in my controller ;)
update
k routing is solved ;) i just added an extra route
//angularjs
var promise = $http.put("/api/album/category/positionUpdate", update);
//laravel
Route::put('/api/album/category/positionUpdate','CategoryController#positionUpdate');
Try post instead put.
var promise = $http.post("/api/album/category/fakeid", update);
PUT vs POST in REST
PUT implies putting a resource - completely replacing whatever is available at the given URL with a different thing. By definition, a PUT is idempotent. Do it as many times as you like, and the result is the same. x=5 is idempotent. You can PUT a resource whether it previously exists, or not (eg, to Create, or to Update)!
POST updates a resource, adds a subsidiary resource, or causes a change. A POST is not idempotent, in the way that x++ is not idempotent.
By this argument, PUT is for creating when you know the URL of the thing you will create. POST can be used to create when you know the URL of the "factory" or manager for the category of things you want to create.
so:
POST /expense-report
or:
PUT /expense-report/10929
I learned via using following
Laravel+Angular+Bootstrap https://github.com/silverbux/laravel-angular-admin
Laravel+Angular+Material https://github.com/jadjoubran/laravel5-angular-material-starter
Hope this help you understand how to utilize bootstrap & angular and speed up your develop by using starter. You will be able to understand how to pass API request to laravel and get callback response.

Html To PDF in CakePhp Using html2pdf Hangs

I use html2pdf, which is based on TCPDF, in CakePhp to render Views in PDF.
However, sometimes the generation hangs, I mean the browser freezes and never receives data.
There is a way to debug such a behavior? In apache logs I do not see any kind of error...
$this->set(compact('quotation','company','user'));
$view = new View(null, false);
$view->set(compact('quotation','company','user'));
$view->viewPath = 'Quotations';
$view->layout = 'preventivo';
if ($quotation['Quotation']['quotation_type'] == SERVICE)
{
$content = $view->render('print_s_template');
$this->set(compact('content'));
$this->response->type('pdf');
$this->render('print');
the print.ctp has
App::import('Vendor', 'HTML2PDF', array('file' => 'html2pdf'.DS.'html2pdf.class.php'));
$html2pdf = new HTML2PDF('P','A4','it');
$html2pdf->WriteHTML($content);
$html2pdf->Output('exemple.pdf');
and the html is in print_s_template.ctp.
I found a solution myself. The problem is that I forgot to pass some variables to the View $view. And I suppose cake throw an error which, next, html2pdf cannot "render".
So: double check that all the variables in the view do exist!

Mobile Version Of My Web App With ZF2

I have developed a web application with zf2. And I have also developed it for mobile devices.
But I cannot decide how can I pass this variable to controller visitor is mobile or not ... for example I want to reach to controller to isMobile or not from view.
Or do you suggest any other way?
//Application\Module.php
public function onBootstrap(MvcEvent $e){
$mobileDetect = $serviceManager->get('MobileDetect'); //Retrieve "\Mobile_Detect" object
//I want to reach to this value (isMobile or not) from my view. but how can do this?
$isMobile = $mobileDetect->isMobile();
}
It seems that you want to access the $isMobile variable in the view files.
If that is so, then try this -
after $isMobile = $mobileDetect->isMobile();
write -
$e->getViewModel()->setVariables(
array(
'isMobile' => $isMobile,
)
);
then in any view files, you can access it as $isMobile and you will get the set value.
I hope this helps.

Restrict External Access to Controller, but enable access from Model (CakePHP 2.X)

In our application we are using the Controller and View to generate a PDF file which can be emailed to a user, the Controller renders a view file and passes it back to the model.
It has been setup like this because in another part of the application we use the same view file to display the PDF on-page (which requires POST data).
My problem is that I need to be able to access the controller functions from my model, however I want to prevent someone (using the website directly) from executing the controller function directly.
In Model:
$Contents = new ContentsController();
$message = $Contents->generatePDF($viewVars);
In Controller:
public function generatePDF($input_data)
{
//set the original data and the check result to build the page:
foreach($input_data as $key => $value)
{
$this->set($key, $value);
}
//instantiate a new View class from the controller
$view = new View($this);
$viewData = $view->render('pdf_file', 'pdf');
return $viewData;
}
Which works, however if the user goes and types /Contents/generatePDF into their browser they can access this controller function, so I want to be able to prevent it being accessed from the web directly.
I am using CakePHP 2.X
The simplest approach is to prepend an underscore to the name of your controller method: _generatePDF. Such methods are not accessible via browser.

CakePHP - spitting out XML for webservice

What is the best way to spit out XML for webservice in CakePHP?
I have it like the following but it's displaying an empty page.
Sample call /service/config.xml
In Controller
var $helpers = array('Xml');
function config() {
$this->autoRender = false;
$obj = array("response" => array("config" => array(...)));
$objXmlHelper = new XmlHelper();
$objXml = $objXmlHelper->header();
$objXml .= $objXmlHelper->serilize($obj);
echo $objXml;
}
That gives empty page. However, if I echo json_encode($obj); that actually prints out json.
Thanks,
Tee
You probably have an error in your code. My guess is you are not including the XML helper.
Check you CakePHP (app/tmp/logs/) and PHP logs. In addition you may need to set the DEBUG flag to a higher level ( i.e. > 0).
I'd also recommend considering moving such things to a model. Web Services are typically data access layers and that belongs in the Model.

Resources