drupal 7 : create xls file with views bulk operation - php

I'm trying to generate an excel file using PHPExcel Module in the action_info function with the following code :
function mymodule_export_data_action(&$object, $context = array()) {
if (isset($object->uid)) {
$uid = $object->uid;
}
elseif (isset($context['uid'])) {
$uid = $context['uid'];
}
if ($uid) {
module_load_include('inc', 'phpexcel');
$filename = 'mymodule--download-' . uniqid() . '.xls';
$filepath = variable_get('file_public_path', conf_path() . '/files') . '/' . $filename;
$result = phpexcel_export(
array('Nom', 'Prenom', 'Date de naissance', 'Adresse email'),
array(
array('A1', 'B1'),
array('A2', 'B2'),
), $filepath);
if ($result === PHPEXCEL_SUCCESS) {
drupal_set_message(l('Click to download', $filepath));
}
else {
}
}
}
This is working pretty fine when having just one node, but when there's more than one it generates a new file for each one, which also good but my purpose is to have one file for all nodes. It has been days and I really hope for someone to put me in the right direction.
Thank you in advance

Here is the solution by using views module, views_data_export module, 2 lines of PHP code and some lines of jQuery.
Just follow these steps:
1st Install views and views_data_export modules
2nd (a) Create views page and data export, this video
will help you to export the data according to the
filter(s)
2nd (b) Don't forget to add nid field in the views page that will use to get NIDs
2nd (c) Now, create one more views data export (that again starts here, if you need) and create exporting PATH different than the first data export (created on step 2nd (a)) but keep remember you don't have to update Attach to option under the DATA EXPORT SETTINGS section, it should looks like this Attach to: none.
2nd (d) Now, add nid as contextual filter in the views and choose Provide default value = Content ID from URL like this and check the checkbox Allow multiple values like this
3rd Add two lines of PHP code somewhere in the template.php OR top of the tpl of views page if you have already created (by the way I did it with the tpl named as views-view--export-multiple-rows--page.tpl.php).
if($_SERVER['REQUEST_METHOD'] == 'POST') {
drupal_goto("export_selected/".implode(',', $_POST['export']));
}
4th Add below jQuery code in the JS file that will be render on this page like custom.js and **change classes **
jQuery(function($){
jQuery('.feed-icon a:first-child').text('Export All');
jQuery('td.views-field-nid').each(function() { //class of NID added in step 2nd (b)
var t = jQuery(this);
var id = jQuery.trim(t.text());
t.html('<input type="checkbox" name="export[]" value="" />');
t.find('input').val(id);
});
//Below .view-export-multiple-rows class is of views class (main views page)
$('.view-export-multiple-rows').wrap('<form method="POST" class="export-form"></form>');
$('.export-form .view-content').append('<input type="submit" value="Export Selected" name="submit" />');
});
If you follow all these steps properly, I believe you have done with:
To export all rows
To export filtered rows
To export specific rows
I hope this will help you or at least give you an idea.
Thanks

Related

Drupal 8 change image style in first row on views list

I have created view that displays on page 10 newest article. I have in row two fields: image and content. In settings of image field I chose image style (for example: medium). How can I change image style to another (example: large) only in first row?
I have tried it in preprocess but i don't know where is stored information about image style:
function theme_preprocess_views_view_unformatted__lista_depesz_default(&$variables) {
$view = $variables['view'];
$rows = $variables['rows'];
$style = $view->style_plugin;
$options = $style->options;
$variables['default_row_class'] = !empty($options['default_row_class']);
foreach ($rows as $id => $row) { $variables['rows'][$id] = array();
$variables['rows'][$id]['content'] = $row;
$variables['rows'][$id]['attributes'] = new Attribute();
if ($row_class = $view->style_plugin->getRowClass($id)) {
$variables['rows'][$id]['attributes']->addClass($row_class);
}
if ($id == 0 && $row['content']['#row']->_entity->field_image[0] != NULL) {
//some php code to change image style
}
}
}
Regards
You can create view with original images, and set style inside your twig files, using for example twig tweak:
https://www.drupal.org/project/twig_tweak
Inside twig file you can set any style with conditioning
{{ 'public://images/ocean.jpg' | image_style('thumbnail') }}
Regarding your code and your explanations, I'm not sure to understand what you are trying to achieve.
1/ you try to add a CSS class to the 1st image of your view. Why not using the following CSS path .my_view .first img {}
2/ if you try to call another image style, can you create a view with only the 1st item, or a promoted? Then a second view with the rest of the items ?
3/ if you try to call another image style, you can do it without any code.
You install the module http://drupal.org/project/views_conditional then you add 2 images with 2 different image style, and you apply your condition inside the condition fieldset.
I really prefer the solution 3 because it's pure Drupal build.
I hope it helps.
Cheers

How do I use the Cohort form in my plugin

How do I use the Form for creating a Cohort in Moodle in my own plugin?
I want to use the form, create the Cohort and return to a URL specified by with the Cohort id as a GET parameter ie http://myip/moodle/myplugin/myscrip.php?cohort_id=0
I've taken a look at the moodle files for the form but it's all chinese for me as i'm a complete novice as it comes to moodle development. What is the 'nice' way of using it?
The forms take a bit of getting used to, they are based on quickforms.
https://docs.moodle.org/dev/Form_API
https://docs.moodle.org/dev/lib/formslib.php_Usage
https://docs.moodle.org/dev/lib/formslib.php_Form_Definition
Usually there is a file named edit.php which uses the class in edit_form.php - but the file names can be anything.
You could take a copy of /cohort/edit.php and put it into your local plugin. If you are only creating cohorts and not updating them, then remove the update and delete code and keep the add cohort code:
$cohortid = cohort_add_cohort($data);
if ($usetags) {
if (isset($data->otags)) {
tag_set('cohort', $cohortid, tag_get_name($data->otags));
} else {
tag_set('cohort', $cohortid, array());
}
}
//update textarea
$data = file_postupdate_standard_editor($data, 'description', $editoroptions, $context, 'cohort', 'cohort', $cohortid);
$DB->set_field('cohort', 'description', $data->description, array('id' => $cohortid));
Then redirect to your link
$url = new moodle_url('/myplugin/myscrip.php', array('cohort_id' => $cohortid));
redirect($url);

How to preload <options> and <select> with Jquery-option-tree plugin

I am using Jquery-option-tree plugin on a standalone website not based on Wordpress as in example 7 on the demo page, except that I am not passing a .txt file but a PHP page is generating the array of < options > to be passed to the plugin.
http://kotowicz.net/jquery-option-tree/demo/demo.html
This perfectly works: so let's say that the user wants to select a category for a new product, the plugin suits the purpose generating a nice: " Food -> fruit -> apples " upon user clicks. (see demo page ex. 7)
What instead if a product already exists with its categories assigned? I want to show it to the user when he edit that product, preloading the tree.
I have the ids path coming from database, so it would just be a matter of having the plugin to run without the user interact, using the value I pass. I saw this question: jQuery simulate click event on select option
and tried to simulate user' click with this (and other) methods with no luck.
$('#select')
.val(value)
.trigger('click');
Here the call to the function:
$(function() {
var options = {
empty_value: '',
set_value_on: 'each',
indexed: true, // the data in tree is indexed by values (ids), not by labels
on_each_change: '/js/jquery-option-tree/get-subtree.php', // this file will be called with 'id' parameter, JSON data must be returned
choose: function(level) {
return 'Choose level ' + level;
},
loading_image: '/js/jquery-option-tree/ajax-load.gif',
show_multiple: 10, // if true - will set the size to show all options
choose: ''
};
$.getJSON('/js/jquery-option-tree/get-subtree.php', function(tree) { // initialize the tree by loading the file first
$('input[name=parent_category_id]').optionTree(tree, options);
});
});
Here you can see the plugin:
https://code.google.com/p/jquery-option-tree/
I don't know that plugin, but looking at the examples there seems to be one that fits your need; Example 6 - AJAX lazy loading & setting value on each level change.
This would, in theory, just require some config options:
preselect: {'demo6': ['220','226']}, // array of default values - if on any level option value will be in this list, it will be selected
preselect_only_once: true, // prevent auto selecting whole branch when user maniputales one of branch levels
get_parent_value_if_empty: true,
attr: "id" // we'll use input id instead of name
If this doesn't fit you need though, you could initiate it from an event, like change, keyup, etc.
$(document).on('change', '#select', function() {
$('#nextSelect').val($(this).val());
})
$(document).on('change', '#nextSelect', function() {
$('#finalInput').val($(this).val());
})
Yes, you are right Mackan ! I saw that "preselect" option but I was initially unable to use it transferring the path from database to javascript, I ended up with my "newbie" solution to match the syntax:
preselect: {'parent_category_id': [0,'2','22']},
PHP
$category_path comes from DB query and is like "0,2,76,140,"
$path = explode(',', $category_path);
$preselect="";
foreach ($path as $value) {
$int = (int)$value;
if ($int != 0) $preselect.= "'". $int ."',";
else $preselect.= $int.","; // have to do this as ZERO in my case has to be without apostrophes ''
}
$preselect = "{'parent_category_id':[".$preselect."]}"
JS
var presel= <?php echo($preselect); ?>;
var options = {
preselect: (presel),
}
Any suggestion for a better code ?
Thanks a lot !!

drupal 7- moving and displaying uploaded image in custom module

I am developing a custom module in which I want to:
Upload an image through a form.
Move image from default folder to my desired folder.
And finally display the image under the same form (below the submit button).
I've achieved the first goal by implementing hook_menu and hook_form but I am stucked very badly in the remaining two goals for last 3 days. Whenever I try to move uploaded image from default folder I get the error message of "Invalid location" and for the third point I didn't understand what to do? I want when the user selects the image and submits the form the image is displayed on the same page under the submit button. Any help would be really appreciated. Here's my code:-
function create_ad_form($form, &$form_submit)
{
...
$form['image_file'] = array(
'#title' => t('Upload Banner:'),
'#type' => 'file'
);
$form['#attributes']['enctype'] = 'multipart/form-data';
...
}
function create_ad_form_submit($form, &$form_state)
{
$module=drupal_get_path('module', 'create_ad');
$validators = array();
$file = file_save_upload('image_file', $validators,"public://",FILE_EXISTS_RENAME);
if ($file)
{
$file->status=FILE_STATUS_PERMANENT;
file_save($file);
$result = file_unmanaged_copy($file, $module, FILE_EXISTS_RENAME);
if ($result == 1)
{
}
else
{
drupal_set_message('Couldn\'t copy file: '.$file->name);
}
}
else
{
form_set_error('create_ad', t("Failed to save the file."));
}
}
I've managed to display the image, however still can't move the image to any folder so placed them in the default "public://" directory. Display image on the same page without ajax is discussed here: Drupal 7 FAPI- Adding form elements in validate or submit handlers and with ajax discussed here: Drupal 7 FAPI - ajax image preview

How to count the number of user downloads

This code for extract files dir and title. The user download when clicked the file link. I need to count then number of downloads. How to do this with cakephp or php?
downloads_controller.php:
function index() {
$this->set('downloads', $this->paginate());
}
downloads/index.ctp:
<?php
$title = $download['Download']['title'];
// output filetitle
$filename = '/files/'.$download['Download']['filename'];
// output http://localhost/tet/files/un5titled0.rar
echo $this->Html->link($title, $filename,array('escape' => false));
?>
not this way i am afraid.
you either need to redirect from an action (which counts before redirecting) or use Media view to pass it through.
thats how I do it.
In the action you can then raise the count prior to sending the file.
If you want to count downloads, you should create a function that serves those downloads and create a field in your database that increments downloads each time this function is called.. For example
Call the following function from your view passing the $filename and the $id
To try out at first use, taking ID=4 as one of the downloads ID in your DB
http://www.yourdomain.com/downloads/download/4
And Then your controller would be...
Class DownloadsController extends AppController{
// All your other functions here
function download($id = null){
$this->Article->updateAll(
array('Download.count' => 'Download.count+1'),
array('Download.id' => $id)
);
$download = $this->Download->findById($id);
$this->set('filename', $download['Download']['filename']);
//$filename is an array that can then be used in your view to pass the file for download. to find out what is has you can use debug($filename) in your view
}
}
Then you need to create a special layout so the browser knows that the request file is a download and you will also need to create a view for download.ctp. Basically when you click the file link on your page, it will call this function which will use its view to serve the file.
You can access the following which will provide some insight on what needs to be done..
TUTORIAL LINK
There are lots of techniques, though in the simplest way, you can use a text file to do this.
Create a txt file and write 0 (zero) into it.
In your index function, read the content of your file.
$counter = file_read_contents('counter.txt');
Increase the read value by 1.
$counter++;
Write new value into file again.
file_put_contents('counter.txt', $counter);
So, it counts downloads and keep number in that file.
function download($id = null) {
$download = $this->Download->findById($id);
$this->set(compact('download'));
if(!empty($id)) {
// increment the number of items downloads
$this->Download->save(array(
'Download' => array(
'id' => $id,
'counts' => ($download['Download']['counts'] + 1)
)
));
}
header('Location: http://localhost/tet/files/'.$download['Download']['filename']);
exit();
}

Categories