Is there any function in Leandash to mark complete COURSE programmatically - wordpress

I am working on Leandash Project , Now my requirement is some students have completed the course offline , So I have created a screen for a group leader in which the group leader can select group/user/course and also add date like this ( https://prnt.sc/1bfcq3a ) and can mark complete COURSE.
So my question is how do I mark complete COURSE. programmatically on link click.
here is my code , which is not working
jQuery(document).on('click', '.course_complete_save', function(event) {
event.preventDefault();
var selected_group_id = jQuery('#group_name_select_dropdown').val();
var selected_user_id = jQuery('#user_name_select_dropdown').val();
var selected_course_id = jQuery('#course_name_select_dropdown').val();
var mark_complete_date = jQuery('#input_date_field').val();
var params = {"mark_complete_date":mark_complete_date,"selected_group_id":selected_group_id,"selected_user_id":selected_user_id,"selected_course_id":selected_course_id,action:"mark_complete_course_ajax"}
jQuery.post(groupcustomisation.ajaxurl,params,function(data){
if(data){
jQuery(".mark_complete_success").empty().append("Mark Completed");
}else{
jQuery(".mark_complete_success").empty().append("No data Found");
}
});
});
<?php
add_action('wp_ajax_nopriv_mark_complete_course_ajax', 'mark_complete_course_ajax');
add_action('wp_ajax_mark_complete_course_ajax', 'mark_complete_course_ajax');
function mark_complete_course_ajax() {
$selected_group_id = $_POST['selected_group_id'];
$selected_user_id = $_POST['selected_user_id'];
$selected_course_id = $_POST['selected_course_id'];
$mark_complete_date = $_POST['mark_complete_date'];
learndash_process_mark_complete( $selected_user_id, $selected_course_id, true, $selected_course_id );
echo "1";
die();
}

Funny enough, i found myself needing solution to same problem minutes after you posted this yesterday and as you see, that function above failed to work and nothing useful online. In short, i spent the whole day on it trying to find why until i realized all lessons and quiz need to be marked as complete too and after writing the function that do exactly this based on my research on learndash source code as primary source, i decided to come back here and post the function just incase you haven't fix it
Usage: sci_learndash_mark_course_complete($course_id, $user_id)
Here's the function:
/**
* Mark learndash course as complete.
*
* #param int $id Course ID.
* #param int $user_id User ID.
*/
function sci_learndash_mark_course_complete($id, $user_id)
{
//retreive current course progress
$user_progress['course'][$id] = learndash_user_get_course_progress($user_id, $id, 'legacy');
if (isset($user_progress['course'][$id]['lessons'])) {
//update lessons progress to complete
$lesson_array = $user_progress['course'][$id]['lessons'];
$lessons = array_flip($lesson_array);
$lessons = array_fill_keys(array_keys($lesson_array), 1);
$user_progress['course'][$id]['lessons'] = $lessons;
}
//update topics progress to complete
if (isset($user_progress['course'][$id]['topics'])) {
foreach($user_progress['course'][$id]['topics'] as $ldtopic_key => $ldtopic){
if(count($ldtopic) > 0){
$new_ldtopic = array_flip($ldtopic);
$new_ldtopic = array_fill_keys(array_keys($ldtopic), 1);
$user_progress['course'][$id]['topics'][$ldtopic_key] = $new_ldtopic;
}
}
}
//update quiz progress to complete
if (isset($user_progress['quiz'][$id])) {
$quiz_array = $user_progress['course'][$id]['quiz'];
$quiz = array_flip($quiz_array);
$quiz = array_fill_keys(array_keys($quiz_array), 1);
$user_progress['course'][$id]['quiz'] = $quiz;
}else{
$quiz_list = [];
if ( isset($user_progress['course'][$id]['lessons']) && count($user_progress['course'][$id]['lessons']) > 0 ) {
$ld_lesson_keys = array_keys($user_progress['course'][$id]['lessons']);
foreach($ld_lesson_keys as $course_lesson_id){
$topic_quizzes = learndash_get_lesson_quiz_list( $course_lesson_id );
if (!empty($topic_quizzes)){
foreach ($topic_quizzes as $topic_quiz) {
$quiz_list[$topic_quiz['post']->ID] = 1;
}
}
}
}
if (!empty($quiz_list)){
$user_progress['quiz'][$id] = $quiz_list;
}
}
$processed_course_ids = [];
if ((isset($user_progress['course'])) && (!empty($user_progress['course']))) {
$usermeta = get_user_meta($user_id, '_sfwd-course_progress', true);
$course_progress = empty($usermeta) ? [] : $usermeta;
$course_changed = false; // Simple flag to let us know we changed the quiz data so we can save it back to user meta.
foreach ($user_progress['course'] as $course_id => $course_data_new) {
$processed_course_ids[intval($course_id)] = intval($course_id);
if (isset($course_progress[$course_id])) {
$course_data_old = $course_progress[$course_id];
} else {
$course_data_old = [];
}
$course_data_new = learndash_course_item_to_activity_sync($user_id, $course_id, $course_data_new,
$course_data_old);
$course_progress[$course_id] = $course_data_new;
$course_changed = true;
}
if (true === $course_changed) {
update_user_meta($user_id, '_sfwd-course_progress', $course_progress);
}
}
if ((isset($user_progress['quiz'])) && (!empty($user_progress['quiz']))) {
$usermeta = get_user_meta($user_id, '_sfwd-quizzes', true);
$quizz_progress = empty($usermeta) ? [] : $usermeta;
$quiz_changed = false; // Simple flag to let us know we changed the quiz data so we can save it back to user meta.
foreach ($user_progress['quiz'] as $course_id => $course_quiz_set) {
foreach ($course_quiz_set as $quiz_id => $quiz_new_status) {
$quiz_meta = get_post_meta($quiz_id, '_sfwd-quiz', true);
if (!empty($quiz_meta)) {
$quiz_old_status = !learndash_is_quiz_notcomplete($user_id, [$quiz_id => 1], false, $course_id);
// For Quiz if the admin marks a qiz complete we don't attempt to update an existing attempt for the user quiz.
// Instead we add a new entry. LD doesn't care as it will take the complete one for calculations where needed.
if ((bool)true === (bool)$quiz_new_status) {
if ((bool)true !== (bool)$quiz_old_status) {
if (isset($quiz_meta['sfwd-quiz_lesson'])) {
$lesson_id = absint($quiz_meta['sfwd-quiz_lesson']);
} else {
$lesson_id = 0;
}
if (isset($quiz_meta['sfwd-quiz_topic'])) {
$topic_id = absint($quiz_meta['sfwd-quiz_topic']);
} else {
$topic_id = 0;
}
// If the admin is marking the quiz complete AND the quiz is NOT already complete...
// Then we add the minimal quiz data to the user profile.
$quizdata = [
'quiz' => $quiz_id,
'score' => 0,
'count' => 0,
'question_show_count' => 0,
'pass' => true,
'rank' => '-',
'time' => time(),
'pro_quizid' => absint($quiz_meta['sfwd-quiz_quiz_pro']),
'course' => $course_id,
'lesson' => $lesson_id,
'topic' => $topic_id,
'points' => 0,
'total_points' => 0,
'percentage' => 0,
'timespent' => 0,
'has_graded' => false,
'statistic_ref_id' => 0,
'm_edit_by' => get_current_user_id(), // Manual Edit By ID.
'm_edit_time' => time(), // Manual Edit timestamp.
];
$quizz_progress[] = $quizdata;
if (true === $quizdata['pass']) {
$quizdata_pass = true;
} else {
$quizdata_pass = false;
}
// Then we add the quiz entry to the activity database.
learndash_update_user_activity(
[
'course_id' => $course_id,
'user_id' => $user_id,
'post_id' => $quiz_id,
'activity_type' => 'quiz',
'activity_action' => 'insert',
'activity_status' => $quizdata_pass,
'activity_started' => $quizdata['time'],
'activity_completed' => $quizdata['time'],
'activity_meta' => $quizdata,
]
);
$quiz_changed = true;
if ((isset($quizdata['course'])) && (!empty($quizdata['course']))) {
$quizdata['course'] = get_post($quizdata['course']);
}
if ((isset($quizdata['lesson'])) && (!empty($quizdata['lesson']))) {
$quizdata['lesson'] = get_post($quizdata['lesson']);
}
if ((isset($quizdata['topic'])) && (!empty($quizdata['topic']))) {
$quizdata['topic'] = get_post($quizdata['topic']);
}
/**
* Fires after the quiz is marked as complete.
*
* #param arrat $quizdata An array of quiz data.
* #param WP_User $user WP_User object.
*/
do_action('learndash_quiz_completed', $quizdata, get_user_by('ID', $user_id));
}
} elseif (true !== $quiz_new_status) {
// If we are unsetting a quiz ( changing from complete to incomplete). We need to do some complicated things...
if (true === $quiz_old_status) {
if (!empty($quizz_progress)) {
foreach ($quizz_progress as $quiz_idx => $quiz_item) {
if (($quiz_item['quiz'] == $quiz_id) && (true === $quiz_item['pass'])) {
$quizz_progress[$quiz_idx]['pass'] = false;
// We need to update the activity database records for this quiz_id
$activity_query_args = [
'post_ids' => $quiz_id,
'user_ids' => $user_id,
'activity_type' => 'quiz',
];
$quiz_activity = learndash_reports_get_activity($activity_query_args);
if ((isset($quiz_activity['results'])) && (!empty($quiz_activity['results']))) {
foreach ($quiz_activity['results'] as $result) {
if ((isset($result->activity_meta['pass'])) && (true === $result->activity_meta['pass'])) {
// If the activity meta 'pass' element is set to true we want to update it to false.
learndash_update_user_activity_meta($result->activity_id, 'pass',
false);
// Also we need to update the 'activity_status' for this record
learndash_update_user_activity(
[
'activity_id' => $result->activity_id,
'course_id' => $course_id,
'user_id' => $user_id,
'post_id' => $quiz_id,
'activity_type' => 'quiz',
'activity_action' => 'update',
'activity_status' => false,
]
);
}
}
}
$quiz_changed = true;
}
/**
* Remove the quiz lock.
*
* #since 2.3.1
*/
if ((isset($quiz_item['pro_quizid'])) && (!empty($quiz_item['pro_quizid']))) {
learndash_remove_user_quiz_locks($user_id, $quiz_item['quiz']);
}
}
}
}
}
$processed_course_ids[intval($course_id)] = intval($course_id);
}
}
}
if (true === $quiz_changed) {
update_user_meta($user_id, '_sfwd-quizzes', $quizz_progress);
}
}
if (!empty($processed_course_ids)) {
foreach (array_unique($processed_course_ids) as $course_id) {
learndash_process_mark_complete($user_id, $course_id);
learndash_update_group_course_user_progress($course_id, $user_id);
}
}
}

Related

Update post terms in each languages by code

who can hellp with this, i need create post from code, by wp_insert_post
function, so what is going on:
I creating post on each existing laguages, then i update all needed fields and i need to set post term depened of current language.
I have terms (shelters) https://prnt.sc/pklSXojB2jZj - i need that post set to current lang shelter while create, but after creating i got - https://prnt.sc/pz2jFEq1OAMP , 2 posts set in one lang terms. Maybe who know whats goes wrong, below i provided 2 functions who do these actions, Thanks in advance:
function add_pet($form_data, $ready_data, $update_meta = false) {
$allLang = pll_languages_list();
if ($allLang) {
$postsArr = array();
foreach ($allLang as $lang) {
//Add new pet
$post_id = wp_insert_post(array(
'post_title' => $form_data['pet_name'],
'post_status' => 'publish',
'post_author' => $form_data['user_id'],
'post_type' => 'pets',
));
//Check if post created, update all needed fields, and update post terms (shelter)
if ($post_id) {
//Get all translation of term
$shelter_id = pll_get_term(intval($form_data['shelter']), $lang);
$update_meta['shelter'] = $shelter_id;
//In this function we update those terms
$update_success = update_pets_fields($post_id, $ready_data, $update_meta);
$postsArr[$lang] = $post_id;
pll_set_post_language($post_id, $lang);
$postDate = get_post($post_id)->post_date;
$unixDate = strtotime($postDate);
update_post_meta($post_id, 'pet_update_date', $unixDate);
}
}
//Save post translation
if ($postsArr) {
pll_save_post_translations($postsArr);
}
//Old code
// foreach ($allLang as $lang) {
// $cat_id = pll_get_term(intval($form_data['kind_of_animal']), $lang);
// $shelter_id = pll_get_term(intval($form_data['shelter']), $lang);
// $post_id = $postsArr[$lang];
// $update_meta['post_category'] = $cat_id;
// $update_meta['shelter'] = $shelter_id;
// $update_success = update_pets_fields($post_id, $ready_data, $update_meta);
// }
}
if (is_wp_error($post_id)) {
wp_send_json_error($post_id->get_error_message());
}
if ($update_success) {
wp_send_json_success('Post was created.');
} else {
wp_send_json_error('Post was not created.');
}
}
And function who update field
/Update pets fields
function update_pets_fields($post_id, $data, $update_meta = false) {
if (!$post_id) return;
//Update post meta data not acf
if (isset($update_meta) && !empty($update_meta['title'])) {
$post_update = array(
'ID' => $post_id,
'post_title' => $update_meta['title']
);
$result = wp_update_post($post_update);
if (is_wp_error($result)) {
wp_send_json_error('Fields was not updated');
}
}
if (isset($update_meta['shelter']) && !empty($update_meta['shelter']) && intval($update_meta['shelter'])) {
wp_remove_object_terms($post_id, 'uncategorized', 'sholters');
$shelter_id = intval($update_meta['shelter']);
wp_set_post_terms($post_id, array($shelter_id), 'sholters');
if (is_wp_error($result)) {
wp_send_json_error('Term not updated');
}
}
if (isset($update_meta['post_category']) && !empty($update_meta['post_category']) && intval($update_meta['post_category'])) {
wp_remove_object_terms($post_id, 'uncategorized', 'category');
wp_set_post_categories($post_id, intval($update_meta['post_category']));
if (is_wp_error($result)) {
wp_send_json_error('Category not updated');
}
}
if (isset($update_meta['thumbnail']) && !empty($update_meta['thumbnail']) && intval($update_meta['thumbnail'])) {
set_post_thumbnail($post_id, intval($update_meta['thumbnail']));
}
if (is_null($data)) {
wp_send_json_error('No data.');
}
foreach ($data as $field) {
if ($field[3] === 'where_is') {
$field_array['field_62169d3cffb5b'] = array(
$field[2] => $field[1],
);
} else {
$field_array = array(
$field[2] => $field[1],
);
}
if (!empty($field[1])) {
$result = update_field('field_621696a7ffb4e', $field_array, $post_id);
}
}
if ($result) {
return false;
} else {
return true;
}
}
I try update it in diferent variants but it does't work, i check ids that come in args all ids is right and all posts ids is right.But on at the exit we got 2 posts in 1 term

How can I override the price string for WooCommerce Subscriptions only for a specific product?

I have this code and I would like to apply it only for a specific product. What would be those extra lines of code for that? Thank you!
add_filter( 'woocommerce_subscriptions_product_price_string_inclusions', 'wpd_override_subscription_price_string', 10, 2 );
function wpd_override_subscription_price_string( $include, $product ) {
/*
'tax_calculation' => get_option( 'woocommerce_tax_display_shop' ),
'subscription_price' => true,
'subscription_period' => true,
'subscription_length' => true,
'sign_up_fee' => true,
'trial_length' => true,
*/
$include['subscription_period'] = false;
$include['sign_up_fee'] = false;
$include['trial_length'] = false;
return $include;
}
If you want to limit by product ID you can do like this
function wpd_override_subscription_price_string( $include, $product ) {
if($product->get_id() !== '1234'){
return $include;
}
$include['subscription_period'] = false;
$include['sign_up_fee'] = false;
$include['trial_length'] = false;
return $include;
}
Cahnge 1234 to your product ID

wp_insert_post called via cron duplicates posts instead of updating them

I'm currently stuck on a problem I can't figure out on a wordpress side project. Here's the thing :
I made a plugin that queries an API, and processes its data to insert posts.
The problem I face is that, when the main function is triggered manually (i.e. via a route or cron manually launched) posts are correctly created or updated, but when the cron executed automatically, posts are always duplicated. I may have narrowed the problem down to capabilities (I check if posts exists by querying the cpt for a unique meta-field), and when the cron executes on its own, it find no ids.
Here are code samples :
public function insertPosts() {
set_current_user(1); // <- here I tried setting the user as admin for the script, but it didn't work
// First, get all prestations from the api
$prestations = $this->api->getPrestations();
/*
* Then :
* we remove sessions of formations initiales, which are useless (gamme id 10 = formations initiales)
* I could have "only" taken the ids I need, but unsetting useless array entries allows for a lighter dataset
*/
$prestations_info = [];
foreach ($prestations as $key => $prestation) {
if ($prestation['gamme']['id'] == 10) {
// Removes the useless $prestation and breaks out of the loop so its ID's not stored
unset($prestations[$key]);
continue;
}
$prestations_info[] = [
'fid' => $prestation['id'],
'cat_name' => $prestation['gamme']['name'],
'cat_id' => $prestation['gamme']['id']
];
}
/*
* Then :
* Parse the array to process every id individually and query the api for core informations for the singles
*/
foreach ($prestations_info as $presta) {
// Meta query to check if a post with the formation's id already exists
$args = [
'post_type' => 'formations',
'posts_per_page' => -1,
'meta_query' => [
[
'key' => 'api_fid',
'value' => $presta['fid'],
'compare' => '='
]
]
];
$posts = new WP_Query($args);
if ($posts->have_posts()) {
while ($posts->have_posts()) {
// If a post with that formation id already exists, we retrieve its ID:
// this way, we can update existing post and avoid duplicates
$posts->the_post();
$post_id = get_the_ID();
}
}
$body = $this->api->getSessionsByPrestationsId($presta['fid']);
$post_array = [];
$locations = [];
$nb_places = [];
foreach ($body as $key => $item) {
if (!empty($item['seances'])) {
$duration = BOUtilities::getFormationDuration($item['seances']);
$dates = BOUtilities::getDatesPerSessions($item['seances']);
}
if ($dates) {
$session_date = [];
if (is_array($dates)) {
foreach ($dates as $i => $date) {
$session_date[$i] = [
'dates' => $date['start'] .' - ' . $date['end'],
];
}
} else {
$session_date[] = [
'dates' => $dates,
];
}
}
if (!empty($item['location'])) {
$locations[] = strtolower($item['location']);
$session[] = [
'sessions_location' => $item['location'],
'sessions_dates' => $session_date,
];
}
if (!empty($item['nbplace']) && $item['nbplace'] != 0) {
if (!in_array($item['nbplace'], $nb_places)) {
$nb_places[] = $item['nbplace'];
}
}
if ($item['price'] != 0) {
$prices[] = $item['price'];
}
}
$formatted_cost = BOUtilities::setPrices($prices);
$effectifs = BOUtilities::setEffectifs($nb_places);
if ($post_id) {
$post_array = [
'ID' => $post_id,
'post_type' => 'formations',
'post_title' => $item['prestation']['name'],
'meta_input' => [
'api_fid' => $presta['fid'],
'aside_cost' => $formatted_cost,
'aside_duration' => ($duration > 1 ? $duration . ' jours' : $duration . ' jour'),
'aside_effectifs' => $effectifs,
]
];
$inserted_post = wp_update_post($post_array);
}
else {
$post_array = [
'post_type' => 'formations',
'post_title' => $item['prestation']['name'],
'meta_input' => [
'api_fid' => $presta['fid'],
'aside_cost' => $formatted_cost,
'aside_duration' => ($duration > 1 ? $duration . ' jours' : $duration . ' jour'),
'aside_effectifs' => $effectifs,
]
];
$inserted_post = wp_insert_post($post_array);
}
// The cron does not have the capability of adding taxonomy terms, they need to be be added separately
$inserted_terms = wp_set_object_terms($inserted_post, $presta['cat_name'], 'categories_formations');
$inserted_terms = wp_set_object_terms($inserted_post, $locations, 'ville');
update_field('aside_sessions', $session, $inserted_post);
unset($dates);
unset($session);
unset($formatted_cost);
unset($nb_places);
unset($prices);
}
}
This is very much work in progress, but, for now, I am stumped.

Woocommerce REST API subscriptions filter by parent_id

I'm using Woocommerce REST API to retrieve some data, code provided by Woocommerce team to use as client
My client options:
'wp_api' => true,
'version' => 'wc/v1',
'ssl_verify' => false,
'wp_api_prefix' => '/wp-json/',
'query_string_auth' => true,
Have a function to retrieve subscriptions:
function get_wc_subscriptions($sid=0, $parent=null, $page=1, $offset=0)
{
$params['page'] = $page;
$params['offset'] = $offset;
$params['role'] = 'all';
if($sid > 0) {
$endpoint = 'subscriptions/'.$sid;
} else {
$endpoint = 'subscriptions';
}
if(isset($parent) && ($parent != null)) {
$params['filter[parent_id]'] = $parent;
}
return $this->wooClient->get($endpoint, $params);
}
Parent parameter is not working, when calling function without any params, I get a result of all subscriptions on first page, if parent is set, get same result with all subscriptions (not being filtered).
Am I missing something?
UPDATE:
How can I use get_wc_subscriptions?
require_once('woosync.php');
$sid = $_GET['sid'];
$parent = $_GET['parent'];
$woosync = new woosync();
$subscriptions = $woosync->get_wc_subscriptions($sid, $parent);
echo "<pre>";
print_r($subscriptions);

Drupal 7 Batch Page Example

I'm trying to setup a batch page for processing and I need an example. The example that's given in the Example module is within a form and I need a page that I can run independently of a form that will process batch requests.
For instance:
function mymodule_batch_2() {
$operations[] = array('mymodule_onefunction','mymodule_anotherfunction')
$batch = array(
'operations' => $operations,
'finished' => 'mymodule_finished',
// We can define custom messages instead of the default ones.
'title' => t('Processing batch 2'),
'init_message' => t('Batch 2 is starting.'),
'progress_message' => t('Processed #current out of #total.'),
'error_message' => t('Batch 2 has encountered an error.'),
);
batch_set($batch);
batch_process('');
}
Where the batch function would call other functions in the form of $operations.
You need to give batch process an id to work from. batch_process('mybatch')otherwise yourmexample is correct. are you having a particular problem with this strategy?
Here you can see my sample of batch relization with form that calls batch:
function my_module_menu() {
$items['admin/commerce/import'] = array(
'title' => t('Import'),
'page callback' => 'drupal_get_form',
'page arguments' => array('my_module_settings_form'),
'access arguments' => array('administer site settings'),
'type' => MENU_NORMAL_ITEM,
);
return $items;
}
/**
* Import form
*/
function my_module_settings_form() {
$form = array();
$form['import'] = array(
'#type' => 'fieldset',
'#title' => t('Import'),
'#collapsible' => TRUE,
'#collapsed' => FALSE,
);
$form['import']['submit'] = array(
'#type' => 'submit',
'#value' => t('Import'),
);
return $form;
}
function my_module_settings_form_submit($form, &$form_state) {
batch_my_module_import_start();
}
/**
* Batch start function
*/
function batch_my_module_import_start() {
$batch = array(
'title' => t('Import products'),
'operations' => array(
array('_batch_my_module_import', array()),
),
'progress_message' => t('Import. Operation #current out of #total.'),
'error_message' => t('Error!'),
'finished' => 'my_module_batch_finished',
);
batch_set($batch);
}
/**
* Import from 1C operation. Deletes Products
*/
function _batch_my_module_import(&$context) {
// Your iterms. In my case select all products
$pids = db_select('commerce_product', 'p')
->fields('p', array('sku', 'product_id', 'title'))
->condition('p.type', 'product')
->execute()
->fetchAll();
// Get Count of products
if (empty($context['sandbox']['progress'])) {
$context['sandbox']['progress'] = 0;
$context['sandbox']['max'] = count($pids);
watchdog('import', 'import products');
}
// Create Iteration variable
if (empty($context['sandbox']['iteration'])) {
$context['sandbox']['iteration'] = 0;
}
// Check for the end of cycle
if ($context['sandbox']['iteration'] < $context['sandbox']['max']) {
// Count of operation in one batch step
$limit = 10;
// Counts completed operations in one batch step
$counter = 0;
if ($context['sandbox']['progress'] != 0) {
$context['sandbox']['iteration'] = $context['sandbox']['iteration'] + $limit;
}
// Loop all Product items in xml
for ($i = $context['sandbox']['iteration']; $i < $context['sandbox']['max'] && $counter < $limit; $i++) {
/* Loop items here */
/* ... */
/* ... */
$context['results']['added']['products'][] = $product_item->title;
// Update Progress
$context['sandbox']['progress']++;
$counter++;
// Messages
$context['message'] = t('Now processing product %name. Product %progress of %count', array('%name' => $product_item->title, '%progress' => $context['sandbox']['progress'], '%count' => $context['sandbox']['max']));
$context['results']['processed'] = $context['sandbox']['progress'];
}
}
if ($context['sandbox']['progress'] != $context['sandbox']['max']) {
$context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
}
}
/**
* Finish of batch. Messagess
*/
function my_module_batch_finished($success, $results, $operations) {
if ($success) {
drupal_set_message(t('#count products added.', array('#count' => isset($results['added']) ? count($results['added']) : 0)));
}
else {
$error_operation = reset($operations);
drupal_set_message(t('An error occurred while processing #operation with arguments : #args', array('#operation' => $error_operation[0], '#args' => print_r($error_operation[0], TRUE))));
}
watchdog('import', 'import finished');
}
function module_name_import_form_submit($form, $form_state) {
// Check to make sure that the file was uploaded to the server properly
$uri = db_query("SELECT uri FROM {file_managed} WHERE fid = :fid", array(
':fid' => $form_state['input']['import']['fid'],
))->fetchField();
if(!empty($uri)) {
if(file_exists(drupal_realpath($uri))) {
// Open the csv
$handle = fopen(drupal_realpath($uri), "r");
// Go through each row in the csv and run a function on it. In this case we are parsing by '|' (pipe) characters.
// If you want commas are any other character, replace the pipe with it.
while (($data = fgetcsv($handle, 0, '|', '"')) !== FALSE) {
$operations[] = array(
'module_name_import_batch_processing', // The function to run on each row
array($data), // The row in the csv
);
}
// Once everything is gathered and ready to be processed... well... process it!
$batch = array(
'title' => t('Importing CSV...'),
'operations' => $operations, // Runs all of the queued processes from the while loop above.
'finished' => 'module_name_import_finished', // Function to run when the import is successful
'error_message' => t('The installation has encountered an error.'),
'progress_message' => t('Imported #current of #total products.'),
);
batch_set($batch);
fclose($handle);
}
}
else {
drupal_set_message(t('There was an error uploading your file. Please contact a System administator.'), 'error');
}
}
/**
* This function runs the batch processing and creates nodes with then given information
* #see
* module_name_import_form_submit()
*/
function module_name_import_batch_processing($data) {
// Lets make the variables more readable.
$title = $data[0];
$body = $data[1];
$serial_num = $data[2];
// Find out if the node already exists by looking up its serial number. Each serial number should be unique. You can use whatever you want.
$nid = db_query("SELECT DISTINCT n.nid FROM {node} n " .
"INNER JOIN {field_data_field_serial_number} s ON s.revision_id = n.vid AND s.entity_id = n.nid " .
"WHERE field_serial_number_value = :serial", array(
':serial' => $serial_num,
))->fetchField();
if(!empty($nid)) {
// The node exists! Load it.
$node = node_load($nid);
// Change the values. No need to update the serial number though.
$node->title = $title;
$node->body['und'][0]['value'] = $body;
$node->body['und'][0]['safe_value'] = check_plain($body);
node_save($node);
}
else {
// The node does not exist! Create it.
global $user;
$node = new StdClass();
$node->type = 'page'; // Choose your type
$node->status = 1; // Sets to published automatically, 0 will be unpublished
$node->title = $title;
$node->uid = $user->uid;
$node->body['und'][0]['value'] = $body;
$node->body['und'][0]['safe_value'] = check_plain($body);
$node->language = 'und';
$node->field_serial_number['und'][0]['value'] = $serial_num;
$node->field_serial_number['und'][0]['safe_value'] = check_plain($serial_num);
node_save($node);
}
}
/**
* This function runs when the batch processing is complete
*
* #see
* module_name_import_form_submit()
*/
function module_name_import_finished() {
drupal_set_message(t('Import Completed Successfully'));
}

Resources