Yii importcsv module headaches - ajax

I have the importcsv module installed and the importcsv page loads fine. The file upload button appears when I load the url- https://web/importcsv
I upload a file, and the ajax "loading" text appears, however the ajax response turns out to be the entire layout of my site and the default importcsv upload page, rather that what I would assume is supposed to load in the importCsvFirstStepResult div (the "next step" fields), after the ajax request in download.js completes
...
onComplete : function(file, response) {
this.enable();
$("input#fileName").val(file);
$("div#importCsvFirstStepResult").html(response);
}
The /importcsv/default/upload ajax response apparently contains the wrong layout, failed to detect the request, or ???? and loads that default view into the response div, menus and all. I'm fairly new to Yii so maybe this is obvious someone out there.
Thanks for your assistance.

Solved my own problem. The ajax issue was due to me having tweaked (breaking) my urlManager rules. I changed the original rules to accomodate non-numeric primary keys on tables. For example the url to view a patient would be https://web/patients/view/ABC_1234 instead of https://web/patients/view/1234
I tend to use existing db schema where possible and the way my clients db schema is set up now, they're using a non-numeric primary key. I wanted to continue this for certain reasons so I had to edit the url params becuase \d only matches digits. Unfortunately changing it to \w also matched some ajax requests and broke the whole thing.
Yii orginal rules. Works fine but doesn't work for alphanumeric primary keys:
'rules'=>array(
'<controller:\w+>/<id:\d+>'=>'<controller>/view',
'<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>',
'<controller:\w+>/<action:\w+>'=>'<controller>/<action>',
),
First I changed it to the following, to handle alphanumeric foreign keys, but this broke some ajax:
'rules'=>array(
'<controller:\w+>/<action:\w+>/<id:\w+>'=>'<controller>/<action>',
'<controller:\w+>/<action:\w+>'=>'<controller>/<action>',
'/gii'=>'/gii/default/login',
),
Finally arrived at the following, which allows ajax modules to function properly, and handles my non-numeric keys:
'rules'=>array(
'/libraries/<action:\w+>/<id:\w+>'=>'/libraries/<action>',
'/patients/<action:\w+>/<id:\w+>'=>'/patients/<action>',
'<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>',
'<controller:\w+>/<action:\w+>'=>'<controller>/<action>',
),
I ended up explicitly setting rules just for the controllers that need it. Most of them use integer primary keys
Hope this helps someone else. I was new to Yii and didn't fully understand the rules and ajax system in Yii when I changed the rules.
Cheers

Related

Link change SESSION var

I have a listing page for an e-commerce website with various items (item_list.php). This page is generated with a PHP loop and displays each item inside a <li> element. Every item is a link to the same page, called item_details.php .
When clicking on the link i want to run a script that changes a SESSION var to a certain $id (which will be excracted from the <li> itself with .innerHTML function) and then allowing the browser to move into the next page (item_details).
This is needed so i can display the proper information about each item.
I think this is possible with Ajax but I would prefer a solution that uses JS and PHP only.
(P.S.This is for a University project and im still a PHP newbie, i tried searching for an answer for a good while but couldn't find a solution)
No JS or other client-side code can set session values, so you need either an ajax call to php, or some workaround. This is not a complete answer, but something to get you thinking and hopefully going on the project again.
The obvious answer is just include it in the link and then get it in PHP from the $_GET -array, and filter it properly.
item title
If, however, there is some reason this is not a question with an obvious answer:
1.) Closest what you're after can be achieved with a callback and an ajax call. The idea is to have the actual link with a click function, returning false so the link doesn't fire at once, which also calls an ajax post request which finally will use document.location to redirect your browser.
I strongly advice against this, as this will prevent ctrl-clicks causing a flawed user experience.
Check out some code an examples here, which you could modify. You will also need an ajax.php file which will actually set the session value. https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce#product-click
2.) Now, a perhaps slightly better approach, if you truly need to do this client-side could be to use an click handler which instead of performing an ajax call or setting session directly, would be to use jQuery to set a cookie and then access this data on the item_list.php -page.
See more information and instructions here: https://www.electrictoolbox.com/jquery-cookies/
<script>
$('product_li a).click(function(){
$.cookie("li_click_data", $(this).parent().innerhtml());
return true;
});
</script>
......
<li class="product_li">your product title</li>
And in your target php file you check for the cookie. Remember, that this cookie can be set to anything, so never ever trust user data. Test and filter it in order to make sure your code is not compromised. I don't know what you want to do with this data.
$_COOKIE['li_click_data'];
3.) Finally, as the best approach, you should look at your current code, and see if there is something you can re-engineer. Here's a quick example.
You could do the following in php to save an array of the values in the session on each page load, and then get that value provided you have some kind of id or other usable identifier for your items:
// for list_items.php
foreach($item as $i) {
// Do what you normally do, but also set an array in the session.
// Presuming you have an id or some other means (here as item_id), to identify
// an item, then you can also access this array on the item_details -page.
$_SESSION['mystic_item_data_array'][$i['item_id]] = $i['thedata'];
}
// For item_details.php
$item_id = // whatever means you use to identify items, get that id.
$data_you_need = $_SESSION['mystic_item_data_array'][$item_id];
Finally.
All above ways are usable for small data like previous page, filters, keys and similar.
Basically, 1 and 2 (client-side) should only be used, if the data is actually generated client-side. If you have it in PHP already, then process it in php as well.
If your intention is to store actual html, then just regenerate that again on the other page and use one of the above ways to store the small data in case you need that.
I hope this gets you going and at least thinking of how to solve your project. Good luck!

Adding custom data based attributes based on Response object

Halo ! I'm trying to implement dropzonejs in a very specific way. Actually I follow the standard implementation described on the official page. Everything works perfectly.
But I'm willing to attach the server's generated URI for each uploaded file directly when uploaded : when uploading it's creating a database entry with some stuff like a page uri with title etc. This mean that the server would return as a response the id of the database saved file in order to attach the href attribute with its value to the the element in front.
This is quite ok to do this when only one file is uploaded, but it becomes trickier when bulk uploading.
So maybe I didn't understand the documentation well (and I'm quite sure I didn't), but is there any way to add custom data-dz-like attributes based on my server's response ? I'd like something like data-dz-url where the url points to a database entity (not the file itself).
Or if not if there is an "easy way" to handle this.
Thanks a lot
Here is the answer :
myDropzone.on('success', (file, response) => {
file.previewElement.href = "/admin/media/"+response.id+"/show/"
})
file is reference to the current uploaded element. It's possible to extend it's html attributes through previewElement. Setting the data-type attribute in the template before, then assigning it the right value works aswell.
Hope this will help some.

Reload TSV File Without Refreshing Page

I've been searching for a day or 2 for an answer to this question, but I haven't found one yet. I've got an external application which is modifying a TSV file (adding data) periodically. I'm using the Basic Line Chart example to display the data and it looks really nice:
Now I want the data to update when the TSV file is updated. I want to be able to set an auto-refresh on the data where it pulls from the tsv file and repopulates the graph without refreshing the entire page.
I tried just wrapping up the current code in a function and calling setInterval on that function, but the data remains the same each time (maybe because it's cached?).
Ideally the solution to this would be a function which can be called to Update whenever I'd like (based on a user event, timer, whatever).
Any ideas, links, or suggestions for alternate ways to accomplish the same goal would be much appreciated!
As a bonus question: I understand D3 may not be the right choice for this sort of Psudo-Real-Time data display. Are there other packages which lend themselves to this sort of thing more? The app generating the data is a C# application (in case that ends up mattering).
Edit: As a supplementary explanation, imagine this example but with the data being read from a file: http://mbostock.github.com/d3/tutorial/bar-2.html
If you are executing an Ajax call to fetch the data from the server and you think caching is a problem, you can try busting the cache by setting the cache parameter in jquery's ajaxSetup to false anywhere in your code:
$.ajaxSetup({cache: false});
From the docs:
If set to false, it will force requested pages not to be cached by the
browser. Note: Setting cache to false will only work correctly with HEAD and
GET requests. It works by appending "_={timestamp}" to the GET parameters. The
parameter is not needed for other types of requests, except in IE8 when a
POST is made to a URL that has already been requested by a GET.

Form is not submitting

My form (Html.BeginForm) was submitting well, i added some records over the period of one month using this form.
Then i did some cleanup (i don't remember those cleanups :( ) and tested the form after some time and now it is not submitting with a date value.
I mean, there are some date fields associated with master and child models, if child's date fields are filled (no matter parent's date is filled or not), the form does not get submitted and if these are empty then it does provided this is the first attempt i.e. if i attempt first with filled dates and then with empty dates, submitting does not work. I have two validation summaries with excludePropertyErrors true and false, no error is shown.
I had custom date format, dd-MMM-yyyy, and respective unobtrusive validator as jQuery.validator.methods["date"]. The behavior is same after removing these on both IE and Chrome.
However, a sample form submitting to the same controller's action on the same view with a sample model depicting the same structure works fine !!!
How to troubleshooting this??
Seems to me that the model binder is working correctly for your expected params, but that specific form is not passing in the values correctly (while your test form does).
These are the things your should try:
Use the browser's built in network logger and see what your POST looks like
Check the cAsE and spellnig of your variable names on the form (they should match your params/POCO on the action signature)
Hope this helps some.
Thanks BiffBaffBoff for compare the two. I figured out the problem by enhancing the sample model, controller and view, adding fields and validations one by one and finally got the issue. It was my authorization action attribute which was missing on one of the Remote validation action for date, my controller requires authorization.
Thank you all who tried to help me out, without even looking at single line of code.

xss protection and html purifier

I am currently using the CodeIgniter framework, and looking to strengthen the XSS protection by using HTMLPurifier (http://htmlpurifier.org/).
Is my understanding correct that you want to 'clean' data on post, so that its purified before its inserted into the Database? Or do I run it before displaying in the view?
If so, do I want to run HTMLPurifier on every single post that takes place? Since the app contains a lot of forms, I'd hate to have to selectively choose what gets cleaned and what doesnt - assuming that I can intercept all posts, is this the way to go? Of course, I validate some fields anyway (like email addresses, numeric numbers, etc)
Use $this->input->post() to get $_POST data. Codeigniter filters it automatically if global xss filter is set to true.
See the docs: http://codeigniter.com/user_guide/libraries/input.html
Edit: to clarify
Yes you should filter before inserting into the DB and yes you should filter all user input.
A quick google search, http://www.google.com/search?q=codeigniter+htmlpurifier, led to this page: http://codeigniter.com/wiki/htmlpurifier which is a helper for htmlpurifier. Regarding catching all $_POST data: you have to do something with the data, right? In your models, when you're doing that something, just make purify() part of that process:
$postdata = purify($_POST);

Resources