Codeigniter modules checking with ajax - codeigniter

Although i can't find a title to fit this need but here is the problem.
I have an existing module called Files. when i use this module some javascript runs and creates thumbs for different kind of files. It is run on windown load.
Now i am developing a module called File Links.
In this module i need to create thumbs on windows load.
I have copied the code from Files module.
Here is some code
public function folder_contents()
{
$parent = $this->input->post('parent');
echo json_encode(Files::folder_contents($parent));
}
This takes the parent parameter coming from ajax request and gets the folder contents.
I want to display all files. For this i have created another method of model that fetches all files.
Now the problem is that while being in File Link Module on load ajax request runs and
hits the method above.
Here is what i have tried
public function folder_contents()
{
$parent = $this->input->post('parent');
$modules = $this->router->fetch_module();
if($modules == 'files'){
echo json_encode(Files::folder_contents($parent));
}else{
echo json_encode(Files::getAllFiles());
}
}
In this method i am checking module name if it is not files then get all files but when ever this method is called module is always files. This method resides in Files Controller. And other thing is that i dont want to write ajax request to point some where else because it is pre-maid and works great.
Now how can i set some condition which will let getAllFiles() run.

The reason why the module always shows as 'files' is because the ajax request does call the Files module regardless of which module triggered the ajax request. It is a separate request.
To get this working you can use the $parent value to determine whether or not you want all files or just the ones with a certain parent folder returned. If you remove the POST value from your custom ajax call then folder_contents() will return all files as shown below.
public function folder_contents()
{
$parent = $this->input->post('parent');
if($parent){
echo json_encode(Files::folder_contents($parent));
}else{
echo json_encode(Files::getAllFiles());
}
}
Since the default ajax call POSTs the folder id it will still return only the files from that folder.

Related

Magento admin - how to create download link to direct file?

I have a PDF file that has been generated in ./var/label/somefile.pdf that I want to provide access to in the shipment area of Magento (specific to an order) as a link, but I am not sure what path to provide for the tag. The preference would be for the link when clicked to start downloading the file to the browser and I only want this link accessible to someone that has been logged into admin.
I've attempted the direct path (http://domain.com/var/label/somefile.pdf) which fails with access error as it should and by trying different versions of getVarDir() to no avail.
Files hacked: sales/order/shipment/view/form.phtml
If you need to check if the visitor is logged into admin you need to pass by a Magento controller.
I assume you know the basis about development with Magento or, at worst, can be helped by someone knowing.
First of all, edit (or create, but you'll also need to create the route) a controller extending Mage_Adminhtml_Controller_Action and add a new method action downloadShipmentPdf
const SHIPMENT_PDF_BASE_DIRECTORY = "/var/www/magentorootfolder/var/label/";
public function downloadShipmentPdfAction() {
$pdfName = $this->getRequest()->getParam('pdf',false);
if ($pdfName) {
$pdfContent = file_get_contents(SHIPMENT_PDF_BASE_DIRECTORY . $pdfName . '.pdf')
if ($pdfContent) {
$this->getResponse()->setHeader('Content-type', 'application/pdf');
$this->getResponse()->setBody($pdfContent);
return;
}
}
}
Now you can generate the admin-compliant URL for your PDF by calling
Mage::helper("adminhtml")->getUrl("modulename/controllername/downloadShipmentPdf", array('pdf' => 'thepdfnamewithoutextension');

Extending Joomla 2.5 Banner Component

I really hope someone can help me.
I need to be able to serve banners in categories which are dependant on a session variable - and can't find a component which does that. So I'd like to extend the Joomla Banner component in order to select banners based on a session variable which contains the category path.
The correct session variable is being stored correctly.
In order to do this I added an option in the banners module .xml to allow for a session variable and the name of the session variable. This is being stored correctly in the module table within the params field along with the other module parameters.
Then I started on the
components > banners > com_banners > models > banners.php
by adding two lines of code in getListQuery where the SQL is assembled. They are:
$sess_vars = $this->getState('filter.sess_vars');
$sess_vars_name = $this->getState('filter.sess_vars_name');
But both variables contain nothing even though the ones the component already has can be retrieved fine. Without a doubt I need to change something somewhere else as well - but just can't figure out what to do.
Any help would be greatly appreciated.
The first thing to do is not hack the core files, hacking the core prevents you from using the built-in update feature to apply the regular bug fixes and security patches released by Joomla! (e.g. the recently released 2.5.9 version).
Rather make a copy of them and modify it so it's called something else like com_mybanners. Apart from the folder name and the entry point file (i.e. banners.php becomes mybanners.php) you will also want to update the components banners.xml to mybanners.php.(You will need to duplicate and modify both the front end /components/com_banners/ and /administrator/components/mybanners.php.)
Because of the way Banners work (i.e. banners are displayed in a module) you will also need to duplicate and modify /modules/mod_banners/,/modules/mod_banners/mod_banners.php and /modules/mod_banners/mod_banners.xml. Changing mod_banners to mod_mybanners in each location.
In Joomla! components the state is usually populated when JModel is instantiated, however, in this case the component is really about managing banners and recording clicks the display is handled by mod_banners. So, you will want to add some code to mod_mybanners.php to use the session variables you want to act on. Normally when a models state is queried you will collect the variables via JInput and add them to your object's state e.g.
protected function populateState()
{
$jApp = JFactory::getApplication('site');
// Load state from the request.
$pk = $jApp->input->get('id',0,'INT');
$this->setState('myItem.id', $pk);
$offset = $jApp->input->get('limitstart',0,'INT');
$this->setState('list.offset', $offset);
// Load the parameters.
$params = $app->getParams();
$this->setState('params', $params);
// Get the user permissions
$user = JFactory::getUser();
if ((!$user->authorise('core.edit.state', 'com_mycomponent')) && (!$user->authorise('core.edit', 'com_mycomponent')))
{
$this->setState('filter.published', 1);
$this->setState('filter.archived', 2);
}
}
The populateState() method is called when a state is read by the getState method.
This means you will have to change your copy of /components/com_banners/models/banner.php to capture your variables into the objects state similar to my example above.
From there it's all your own code.
You can find all of this information in the Developing a Model-View-Controller tutorial on the Joomla Doc's site

Why are images uploaded through the admin panel of my custom module, having the file name of Array?

Here is my BrandController.php
https://gist.github.com/a958926883b9e7cc68f7#file-brandcontroller-php-L53
I've gone through all my files of my custom module, and compared them to the one given from the custom module maker, and I couldn't find much differences.
Are you attempting to upload multiple files? If you're using multiple fileupload elements with the same name you'll get an array of items.
So when the following line is called,
//this way the name is saved in DB
$data['filename'] = $_FILES['filename']['name'];
It will have the value
["name"]=>array(2) {
[0]=>string(9)"file0.txt"
[1]=>string(9)"file1.txt"
}
you'll need to update the code to loop through each $_FILES['filename']['name'] and upload and save the files separately.
You may unknowingly uploaded multiple files. If you that is not your intention, you may check your in your HTML and check the name attribute of the tag. It must not be an array (like this).
<input type="file" name="my_files[]" />
If you only see Array() in your database, it means you are indeed uploading a multiple files. You can process them by using loops.
If you are really sure that you are uploading 1 image, you may follow #Palanikumar's suggestion. Use a print_r() and display the $_FILES and paste it here. IF you don't want to use that, You can use
json_encode($the-data-you-are-going-to-insert-to-the-database);
If you don't know where to put the print_r() function, you may put it after line 56 of this file.
https://gist.github.com/desbest/a958926883b9e7cc68f7#file-brandcontroller-php-L53
if(isset($_FILES['filename']['name']) && $_FILES['filename']['name'] != '') {
print_r($_FILES);
die;
If saveAction() is being called inside an ajax function you need to log the ajax response. Assuming you are using jquery..
$ajaxResponse = $.POST({...});
console.log($ajaxResponse.responseText);
Then, you you can view it inside a browser's console. If nothing appears, you may use a non-async request
$ajaxResponse = $.POST({
// your options,
// your another option,
async: FALSE
});
Usually file upload will return in array format. So that each uploaded file will have the information like name, type, size, temporary name, error. You can get the file information using print function (print_r($_FILES)). So if you want to display name of the file you have to use something like this $_FILES['filename']['name']
Use print function and debugging tool then save file information using loops.
For more info please check here.
You aren't setting the enctype of the form so the image will never be sent. updated the code to
$form = new Varien_Data_Form(array( 'enctype' => 'multipart/form-data'));

Putting AJAX in a Joomla Module

I've made a basic Joomla module for my site as a shoutbox. But I'd like to put AJAX in it (I know a similar module with AJAX already exists on JED but this more a project for me to learn how AJAX works in a Joomla module).
The usual AJAX stuff where you redirect to a new php file obviously doesn't work as the file will not be defined as
defined('_JEXEC') or die('Restricted access');
will fail in a new page. And defining _JEXEC to be equal to one (as I've read in several posts on SO) as far as I've read on Joomla Docs is a security risk as it provides an entry point onto the site.
The way the other shoutbox module I've seen does is to point back at a function in the helper.php file. Which makes sense to me as that is where all the functions should normally be stored. However I'm unclear as to how to the module was accessing the helper.php file on a onSubmit() (or a related) command and was hoping someone could shed some light on this.
I don't actually need anything specific to my shoutbox module - this is more a question of how to get AJAX functionality in Joomla modules and how it is arranged
The other two were onto the right track you need to remember that when you make your AJAX call you can't directly access a php file in Joomla. So instead it's better to make calls to your module. In this case and have the module check for variables in your POST or in the URL.
I'm a big fan of JQuery's ajax it's a lot more self contained than the method the guy who built that shoutbox used.
$( "#addShout" ).click( function(event, ui) {
$.ajax({
type: 'GET',
url: "<?php echo JURI::base() . "index.php?option=mod_mymodule&task=getCustomerJson&selectedCustomer="?>" + encodeURIComponent(value),
success:function(data){
$('#shouts').append(data);
},
error:function(){
$('#errors').html('<p class="error"><strong>Oops!</strong> Try that again in a few moments.</p>');
}
});
});
Then as I mentioned in my comment to Valentin you:
$task = JRequest::getVar('task');
if($task == "getCustomerJson"){mySuperHelper::getCustomerJson();}
You only call the necessary functions when the variables exist.
To explain part of the process it's kinda like this:
If there are no variables in the POST or URL it will simply display the module the way Joomla expects.
If the variable are detected call the method to add it to the database and the javascript function that will add it the the display. Also prevent the normal display from happening.
The module you referenced was quite interesting. The helper functions that the main file referenced does what a model would normally handle in MVC and the Javascript was also kinda all over. If you really want to understand how that one worked you really need to dig into the fatAjax.js file as it contains all of the AJAX and sets the variables that the mod_shoutbox.php listens for.
Fron Joomla 3.2 if you needed to make an AJAX request in Joomla! from a custom module or plugin, you can build the URL as below.
index.php?option=com_ajax&module=your_module_name&method=YourMethodName&format=json
Explanation of each parameter
1. index.php?option=com_ajax : ALL requests must be routed through com_ajax.
2. module=your_module_name: The first part of this is the type of extension you're using. This can either be 'module' or 'plugin'. The second part is the name of the extension. please take care you're not including the prefix 'mod_' or 'plg_', just the name.
3. method=YourMethodName: This is the method name that you are trying to call. If you're using this in a module then the method must be appended with 'Ajax'. So, the method represented here will be YourMethodNameAjax. If you're using this on a plugin, the method must be prepended with 'onAjax'. So, the method represented here will be onAjaxYourMethodName.
Check more at Joomla doc
jQuery(document).ready(function () {
jQuery(".btnshow").click(function () {
var pagename, pid;
pid=jQuery(this).attr('rel');
pagename="<?php echo JURI::root();?>index.php?option=com_componentname&view=result&Id="+pid;
jQuery.get(pagename, function (data) {
jQuery('.para1').html(data);
});
});
});
<img src="<?php echo $image; ?>" alt="" />
From my knowledge you can't do AJAX calls from the module to a function in the module itself (or similar).
You can build a component and create a view which returns RAW or JSON as a response. Because Joomla! itself will be called you can use the Joomla! API & all the goodies from it. It's also a security thing, because if you need to get sensitive data, you can also do ACL / user checks.
When you can call from the module something like:
index.php?option=com_mycomponent&task=getJson
The article Generating JSON output is a good starting point.
You can achieve the desired result by the following way:
$( "#addShout" ).click( function(event, ui) {
$.ajax({
type: 'GET',
url: "<?php echo JURI::base() . "index.php?option=com_ajax&module=module_name_withot_prefix&method=methodName&anyparams="?>" + encodeURIComponent(anyparamsvalue) + "&format=json",,
success:function(data){
$('#shouts').append(data);
},
error:function(){
$('#errors').html('<p class="error"><strong>Oops!</strong> Try that again in a few moments.</p>');
}
});
});
In the module helper file, you'll need to have a method with name 'methodName'.

Calling script on image upload in Drupal

I would like to call a Ruby script when a user uploads an image to my Drupal content-type. I have a CCK image field that serves as the main image, and ImageCache takes care of resizing and creating thumbnails for me.
I have a Ruby script that does some transformations to the image, however I don't exactly know how to call it (no experience with Ruby really). Basically the script applies some image transforms and then generates a new image.
My question is how to call this script from Drupal...is there some sort of hook regarding the CCK image upload that I would hijack?
ImageField uses the same API as FileField. Therefore, you could add a custom validator for your upload field, which would do some checks on the image (like calling a ruby script).
I described that some time ago on Drupal.org, see: http://drupal.org/node/546146
However, for your convenience, here the code.
First, define a validator for the upload form:
function example_form_alter(&$form, $form_state, $form_id) {
if ($form_id != 'ID_OF_YOUR_FORM')
return;
$form['FIELDNAME'][0]['#upload_validators']['example_FUNCTIONNAME'] = array();
return $form;
}
Second, implement the validator function:
function example_FUNCTIONNAME($field) {
// variable for error messages
$errors = array();
// do some processing on the field
$filepath = $field->filepath;
...
// in case of error, add error message
$errors[] = t('Validation failed, because...');
return $errors;
}
Put this code in a custom module, but make sure that your module is called after FileField and ImageField (adjust weight in system table).
Update: There is another way to hook into it. You can use hook_nodeapi to react on operation "presave". This also allows you to call a script on the content of the uploaded field.

Resources