I have an array that loaded data from excel, now I need to send this data to another view for a review of test, but this not found because is a array in a function, I try to use serialize and unserialize but this send a error of limit of characteres in the url.
public function excel() {
$this->loadModel('SoyaProductorCompra');
$excel=array();
$k=0;
if ($this->request->is('post')) {
$datos = new Spreadsheet_Excel_Reader();
$datos->read($this->request->data['SoyaProductorCompra']['excel']['tmp_name']);
for ($i = 2; $i <= $datos->sheets[0]['numRows']; $i++) {
$excel[$k]['producto']=$datos->sheets[0]['cells'][$i][1];
$excel[$k]['toneladas']=$datos->sheets[0]['cells'][$i][2];
$excel[$k]['precio']=$datos->sheets[0]['cells'][$i][3];
$excel[$k]['total']=$datos->sheets[0]['cells'][$i][4];
$excel[$k]['fecha']=$datos->sheets[0]['cells'][$i][5];
$excel[$k]['id']=$datos->sheets[0]['cells'][$i][6];
$k++;
}
$this->set('excels',$excel);
//return $this->redirect(array('action' => 'revision', serialize($excel))); not found
}
}
this is my other function that recive the array and show in my view but not found
public function revicionexcel($data) {
//$data=unserialize($data); not work
//debug($data); not work
}
I wouldn't send the data of a whole spreadsheet through a query string regardless, even if it were small enough to do that. I mean, what would happen if someone started manually editing the URL for instance? Either write the data to a file, or save it in the session instead.
It seems that you're calling the funciton inside the same controller, right?
If so, then why you just don't use:
public function excel()
{
//read excel into $excel variable
$this->revicionexcel($excel);
}
so, no need of redirects here
Although it's recommended that you have the excel reading in the model layer, as this layer is intended for all kind of data management.
Edit:
Then, based on your comments, you can move all the reading to the model, and call it from the controller:
SoyaProductorCompra model:
public function excel($data) {
//your excel reading function as you have it on the controller.
//change all "$this->request->data" references for the parameter "$data"
//be sure to return the excel properly.
...
return $excel;
}
SoyaProductorCompras controller:
public function revision()
{
$excel = $this->SoyaProductorCompra->excel($this->request->data);
$this->set('excels', $excel);
}
What we're doing here is to call the excel opening in the model from the action revision(), and sending them to its view. You don't need to redirect here.
Related
I am working with the save event but having limited luck.
I have currently tried two ways but to limited success.
1) I can either never get the function to fire,
2) I am not too sure what to pass into the function for method two.
All I am trying to do is to dump the event information out on content save.Any help greatly appreciated, really loving this CMS
Attempt One -- never runs the function at all
class Extension extends BaseExtension
{
public function initialize() {
$this->addCss('assets/extension.css');
$this->addJavascript('assets/start.js', true);
$this->app['dispatcher']->addListener(\Bolt\Events\StorageEvents::POST_SAVE, 'postSave');
}
function postSave(\Bolt\StorageEvent $event)
{
dump($event);
}
Attempt two -- what do I input as a parameter?
class Extension extends BaseExtension
{
public function initialize() {
$this->addCss('assets/extension.css');
$this->addJavascript('assets/start.js', true);
$this->app['dispatcher']->addListener(\Bolt\Events\StorageEvents::POST_SAVE,$this->postsave($this->?????));
}
function postSave(\Bolt\StorageEvent $event)
{
dump($event);
}
Hopefully my answer doesn't come too late!
You simply can modify the content and save it back to the database:
public function postSave(\Bolt\Events\StorageEvent $event) {
// get the content
$content = $event->getContent();
// get a field out of the contenttype
$data = $content->get("myField");
// now modify $data here
$data = "new data - what ever you want";
// set data to the content
$content->setValue("data", $data);
// write the modified content to the database
$this->app['storage']->saveContent($content);
}
Note that the function gets fired every time you save contents. So just add an if-statement like this to just modify content you really want to:
if ($event->getContentType() == "my_type")
The parameter needed is a php callback the format for this is something like this:
$this->app['dispatcher']->addListener(\Bolt\Events\StorageEvents::POST_SAVE, array($this, 'postSave'));
That syntax is saying to run the postSave method within the current class. So this would work with your example number 1.
Now you can dump the event in your postSave method and see the results.
I'm using Cakephp with json parse extension and the RequestHandler component in order to create Web services using json.
I created a controller named Ws
In this controller I have a named userSubscribe
In order to avoid a lot of If else statements in the next methods, I thought about using a private function inside this controller that will check somes conditions and stop the script normaly BUT ALSO render the json normaly. I just want to do a DRY way !
My question is :
How could I render the json view in a sub function (called by the userSubscribe) ?
To make it clear, here is the style code that would like
public function userSubscribe() {
$this->check();
// Following code only executed if check didn't render the json view
// $data = ...
$code = 1;
$i = 2;
}
private function check() {
$input = &$this->request->data;
if ($_SERVER["CONTENT_TYPE"] != "application/json") { // For example
$result = "KO";
$this->set(compact("result"));
$this->set('_serialize', 'result');
$this->render(); // HERE, it will stop the 'normal behaviour' and render the json with _serialize
}
if (!isset($input["input"])) {
$result = "KO";
$this->set(compact("result"));
$this->set('_serialize', 'result');
$this->render(); // HERE, it will stop the 'normal behaviour' and render the json with _serialize
}
}
It's seems to be quite simple to do, but why can't I find the answer ?!
Thanks in advance for clue/advise/anything !
I'm trying to pass an array from a function to another function in laravel.
In my PageController.php, I have
public function show($code, $id){
//some code
if(isset($search))
dd($search);
}
and another function
public function search($code, $id){
//some queries
$result = DB::table('abd')->get();
return Redirect::action('PageController#show, ['search'=>$search]);
}
But this returns me an error like this: ErrorException (E_UNKNOWN)
Array to string conversion
I'm using laravel.
You could maybe get it to work with passing by the URL by serialization, but I'd rather store it in a session variable. The session class has this nice method called flash which will keep the variable for the next request and then automatically remove it.
Also, and that's just a guess, you probably need to use the index action for that, since show needs the id of a specific resource.
public function search($code, $id){
//some queries
$result = DB::table('abd')->get();
Session::flash('search', $search); // or rather $result?
return Redirect::action('PageController#index');
}
public function index($code){
//some code
if(Session::has('search')){
$search = Session::get('search');
dd($search);
}
}
I'm trying to figure out how to use one of my view elements inside of a controller...
I know, I know: "Don't do that!" (99% of the time this is the correct answer)
But I think I actually have a good reason. The action is handling an AJAX request which returns markup. The returned markup is a list which I display everywhere else using an element. So in an effort to keep my code DRY, I think it's appropriate to do this here.
Is this possible?
Easy:
$view = new View($this, false);
$content = $view->element('my-element', $params);
Also:
DON'T DO THAT ANYMORE!!!
Sometimes, you need to render a CakePhp element from a view and inject its content into the page using AJAX the same time. In this case rendering element as a regular view from controller is better than creating a dedicated view that just contains <?php echo $this->element('some_element') ?>, and may be done this way:
<?php
public function ajax_action() {
// set data used in the element
$this->set('data', array('a'=>123, 'b'=>456, 'd'=>678));
// disable layout template
$this->layout = 'ajax';
// render!
$this->render('/Elements/some_element');
}
I know this is an old question and other people have already given basically the same answer, but I want to point out that this approach (provided by Serge S.) ...
<?php
public function ajax_action() {
// set data used in the element
$this->set('data', array('a'=>123, 'b'=>456, 'd'=>678));
// disable layout template
$this->layout = 'ajax';
// render!
$this->render('/Elements/some_element');
}
...is not a hacky workaround, but is in fact the recommended approach from the CakePHP docs for this common and legitimate use case:
If $view starts with ‘/’, it is assumed to be a view or element file
relative to the /app/View folder. This allows direct rendering of
elements, very useful in AJAX calls.
(Again: Credit to Serge S. for the code above)
$this->view = '/Elements/myelement';
You should use a client-side template. You should never return mark-up from a web service or API, just data. Have your JavaScript take the data, and then format it how you wish.
For example:
function getItems() {
$.get('/some/url', function(response) {
if (response.data.length > 0) {
for (var i = 0; i < response.data.length; i++) {
var item = response.data[i];
$('.results').append('<li>' + item.title + '</li>');
}
}
});
};
This is just an example written off the cuff. Obviously you’ll need to write your own implementation.
The way I did any ajax handling in Cake was to have my own AjaxController. Any interaction of ajax-kind goes there, which in-turn uses their own views (and view partials / elements). That way you can keep your code DRY and isolate and propagate all ajax use-cases there.
Example excerpt:
<?php
class AjaxController extends AppController {
/**
* (non-PHPdoc)
* Everything going to this controller should be accessed by Ajax. End of story.
* #see Controller::beforeFilter()
*/
public function beforeFilter() {
parent::beforeFilter();
$this->autoRender = false;
$this->layout = false;
if (!$this->request->is('ajax')) {
$this->redirect('/');
}
}
public function preview() {
if ($this->request->is('ajax')) {
$this->set('data', $this->data);
$this->render('/Elements/ajaxpreview');
}
}
?>
Here's the source: https://github.com/Sobient/dosspirit/blob/master/app/Controller/AjaxController.php
I setup the parseExtension for json in my cakephp 2.3.0. No errors are display. It works?
How can I test is?
In RoR ist ist very easy to test via
https://mydomain.de/view/4.json
How does it run on cakephp?
My View-Action is this.
public function view($id = null) {
if (!$this->Atla->exists($id)) {
throw new NotFoundException(__('Invalid atla'));
}
$options = array('conditions' => array('Atla.' . $this->Atla->primaryKey => $id));
$this->set('atla', $this->Atla->find('first', $options));
$this->Atla->id = $id;
$result = $this->Atla->read();
$this->response->type('json');
$this->response->body(json_encode($result));
return $this->response;
$this->set(compact('atlas'));
}
Why i always get an json-request?
If you use the _serialize key cakephp can automatically create json and xml views for you. I typically use the following to create json or xml views:
public function view() {
// data I want to display
$record1 = $this->ModelName->find('first', ...);
$this->set('record1', $record1);
$record2 = $this->ModelName->find('first', ...);
$this->set('record2', $record2);
// option 1: serialize the hard way
$this->set('_serialize', array('record1', 'record2'));
// option 2: serialize the easy way
$this->set('_serialize', array_keys($this->viewVars));
}
PS: the code after your return statement will never be executed.
you'll have create the view
app/View/Atlas/json/view.ctp
which is the view that is being used for .json requests.
Requests without .json will use the regular view file:
app/View/Atlas/view.ctp
There's more information on creating/using JSON and XML views here:
http://book.cakephp.org/2.0/en/views/json-and-xml-views.html#using-a-data-view-with-view-files
From that page the view.ctp may contain something like;
// View code - app/View/Posts/json/index.ctp
foreach ($posts as &$post) {
unset($post['Post']['generated_html']);
}
echo json_encode(compact('posts', 'comments'));
However, it really depends on what you're trying to achieve. If you will only use the 'Atlas/view' action for JSON responses, and won't be using HTML at all, sometimes you can get away with generating the response-body inside your Controller. Not very much 'in line' with MVC conventions, but it saves you from creating a view that does nothing more than echo json_encode($data); ;)
public function view($id)
{
$this->MyModel->id = $id;
$result = $this->MyModel->read();
$this->response->type('json');
$this->response->body(json_encode($result));
//Return reponse object to prevent controller from trying to render a view
return $this->response;
}
If you do want to use both 'HTML' and 'JSON', depending on the request (with/without .json extension), you should have two view files; 1 for JSON and 1 for HTML;
// This view will be used for your JSON requests
app/View/Atlas/json/view.ctp
// This view will be used for non-JSON (html) requests:
app/View/Atlas/view.ctp
In the json-view, output the data using json_encode(.....);
In the 'normal'/html view, just output normal data
In your controller, set the data as normal
public function view($id = null) {
$this->Atla->id = $id;
if (!$this->Atla->exists()) {
throw new NotFoundException(__('Invalid atla'));
}
$this->set('atla', $this->Atla->read());
}