echo ' '; echo '<a href="' . htmlspecialchars($file['file_url']) . '">' . htmlspecialchars($file['file_url']) . '</a>'; } }, 'cell_class' => 'row_action'); $columns['file_description'] = array('title' => 'Description', 'callback' => function ($file) { echo module_security::purify_html($file['description']); }); $columns['file_status'] = array('title' => 'Status', 'callback' => function ($file) { echo nl2br(htmlspecialchars($file['status'])); }); $columns['file_size'] = array('title' => 'Size', 'callback' => function ($file) { if ($file['bucket']) { // how many files are under this bucket? $search = array(); $search['bucket_parent_file_id'] = $file['file_id']; echo _l('%s files', count(module_file::get_files($search))); } else { if (file_exists($file['file_path'])) { echo module_file::format_bytes(filesize($file['file_path'])); } } }); if (!isset($_REQUEST['customer_id'])) { $columns['file_customer'] = array('title' => 'Customer', 'callback' => function ($file) { echo module_customer::link_open($file['customer_id'], true); }); } if (class_exists('module_job', false)) { $columns['file_job'] = array('title' => 'Job', 'callback' => function ($file) { echo module_job::link_open($file['job_id'], true); });
public function delete() { if ($this->file_id && module_file::can_i('delete', 'Files')) { $file_data = $this->get_data(); if ($this->can_i_access()) { // delete any sub files of buckets first. // todo: recurisive testing. if ($file_data['bucket']) { $sub_files = module_file::get_files(array('bucket_parent_file_id' => $file_data['file_id'])); foreach ($sub_files as $sub_file) { if ($sub_file['file_id'] && $sub_file['bucket_parent_file_id'] == $this->file_id) { $sub_file_ucm = new ucm_file($sub_file['file_id']); $sub_file_ucm->delete(); } } } // delete the physical file. if ($file_data['file_path'] && is_file($file_data['file_path'])) { unlink($file_data['file_path']); } // delete the db entry. delete_from_db('file', 'file_id', $this->file_id); // delete any comments. delete_from_db('file_comment', 'file_id', $this->file_id); // delete any staff rel. delete_from_db('file_user_rel', 'file_id', $this->file_id); // delete any notifications delete_from_db('file_notification', 'file_id', $this->file_id); } } }
</div> <?php } ?> </div> <script type="text/javascript"> set_add_del('job_tax_holder'); </script> <?php $fieldset_data['elements']['tax'] = array('title' => 'Tax', 'fields' => array(ob_get_clean())); $fieldset_data['elements']['currency'] = array('title' => 'Currency', 'field' => array('type' => 'select', 'options' => get_multiple('currency', '', 'currency_id'), 'name' => 'currency_id', 'value' => $job['currency_id'], 'options_array_id' => 'code')); // files if (class_exists('module_file', false)) { ob_start(); $files = module_file::get_files(array('job_id' => $job['job_id']), true); if (count($files) > 0) { ?> <a href="<?php echo module_file::link_generate(false, array('arguments' => array('job_id' => $job['job_id']), 'data' => array('job_id' => $job['job_id']))); ?> "><?php echo _l('View all %d files in this job', count($files)); ?> </a> <?php } else { echo _l("This job has %d files", count($files)); } echo '<br/>';
} }, array('type' => 'html', 'value' => '', 'help' => 'Assign a staff member to this file. Staff members are users who have EDIT permissions on Job Tasks. Click the plus sign to add more staff members. You can apply the "Only Assigned Staff" permission in User Role settings to restrict staff members to these files.<br><br>If there are assigned staff members then those members will be the only ones to receive notifications when a change is made to the file. If no staff are assigned to this file then anyone with the "Receive Alerts" permission will receive file change/comment alerts.'))); echo module_form::generate_fieldset($fieldset_data); unset($fieldset_data); hook_handle_callback('layout_column_half', 2); $fieldset_data = array('heading' => array('title' => _l('Bucket Description'), 'type' => 'h3'), 'elements' => array(array('field' => array('type' => 'wysiwyg', 'name' => 'description', 'value' => $file['description'])))); echo module_form::generate_fieldset($fieldset_data); unset($fieldset_data); if ((int) $file_id > 0) { if (module_file::can_i('edit', 'Files')) { module_email::display_emails(array('title' => 'File Emails', 'search' => array('file_id' => $file_id))); } ob_start(); $search = array(); $search['bucket_parent_file_id'] = $file_id; $files = module_file::get_files($search); $table_manager = module_theme::new_table_manager(); $columns = array(); $columns['file_name'] = array('title' => 'File Name', 'callback' => function ($file) { echo module_file::link_open($file['file_id'], true); if (isset($file['file_url']) && strlen($file['file_url'])) { echo ' '; echo '<a href="' . htmlspecialchars($file['file_url']) . '">' . htmlspecialchars($file['file_url']) . '</a>'; } }, 'cell_class' => 'row_action'); $columns['file_description'] = array('title' => 'Description', 'callback' => function ($file) { echo module_security::purify_html($file['description']); }); $columns['file_status'] = array('title' => 'Status', 'callback' => function ($file) { echo nl2br(htmlspecialchars($file['status'])); });
public function delete_customer($customer_id, $remove_linked_data = true) { $customer_id = (int) $customer_id; if ($customer_id > 0) { if (_DEMO_MODE && $customer_id == 1) { set_error('Sorry this is a Demo Customer. It cannot be changed.'); redirect_browser(self::link_open($customer_id)); } $customer = self::get_customer($customer_id); if ($customer && $customer['customer_id'] == $customer_id) { // todo: Delete emails (wack these in this customer_deleted hook) hook_handle_callback('customer_deleted', $customer_id, $remove_linked_data); if (class_exists('module_group', false)) { // remove the customer from his groups module_group::delete_member($customer_id, 'customer'); } if (class_exists('module_extra', false)) { module_extra::delete_extras('customer', 'customer_id', $customer_id); } // remove the contacts from this customer foreach (module_user::get_contacts(array('customer_id' => $customer_id)) as $val) { if ($val['customer_id'] && $val['customer_id'] == $customer_id) { module_user::delete_user($val['user_id']); } } // remove staff delete_from_db('customer_user_rel', 'customer_id', $customer_id); if (class_exists('module_note', false)) { module_note::note_delete("customer", 'customer_id', $customer_id); } handle_hook("address_delete", $this, 'all', "customer", 'customer_id', $customer_id); // todo, check the 'delete' permission on each one of these 'delete' method calls // do that better when we remove each of these and put them into the customer delete hook if ($remove_linked_data) { if (class_exists('module_website', false) && module_website::is_plugin_enabled()) { foreach (module_website::get_websites(array('customer_id' => $customer_id)) as $val) { if ($val['customer_id'] && $val['customer_id'] == $customer_id) { module_website::delete_website($val['website_id']); } } } if (class_exists('module_job', false) && module_job::is_plugin_enabled()) { foreach (module_job::get_jobs(array('customer_id' => $customer_id)) as $val) { if ($val['customer_id'] && $val['customer_id'] == $customer_id) { module_job::delete_job($val['job_id']); } } } if (class_exists('module_invoice', false) && module_invoice::is_plugin_enabled()) { foreach (module_invoice::get_invoices(array('customer_id' => $customer_id)) as $val) { if ($val['customer_id'] && $val['customer_id'] == $customer_id) { module_invoice::delete_invoice($val['invoice_id']); } } } if (class_exists('module_quote', false) && module_quote::is_plugin_enabled()) { foreach (module_quote::get_quotes(array('customer_id' => $customer_id)) as $val) { if ($val['customer_id'] && $val['customer_id'] == $customer_id) { module_quote::delete_quote($val['quote_id']); } } } //handle_hook("file_delete",$this,"customer",'customer_id',$customer_id); } else { // instead of deleting these records we just update them to customer_id = 0 if (class_exists('module_website', false) && module_website::is_plugin_enabled()) { foreach (module_website::get_websites(array('customer_id' => $customer_id)) as $val) { if ($val['customer_id'] && $val['customer_id'] == $customer_id) { update_insert('website_id', $val['website_id'], 'website', array('customer_id' => 0)); } } } if (class_exists('module_job', false) && module_job::is_plugin_enabled()) { foreach (module_job::get_jobs(array('customer_id' => $customer_id)) as $val) { if ($val['customer_id'] && $val['customer_id'] == $customer_id) { update_insert('job_id', $val['job_id'], 'job', array('customer_id' => 0)); } } } if (class_exists('module_invoice', false) && module_invoice::is_plugin_enabled()) { foreach (module_invoice::get_invoices(array('customer_id' => $customer_id)) as $val) { if ($val['customer_id'] && $val['customer_id'] == $customer_id) { update_insert('invoice_id', $val['invoice_id'], 'invoice', array('customer_id' => 0)); } } } if (class_exists('module_quote', false) && module_quote::is_plugin_enabled()) { foreach (module_quote::get_quotes(array('customer_id' => $customer_id)) as $val) { if ($val['customer_id'] && $val['customer_id'] == $customer_id) { update_insert('quote_id', $val['quote_id'], 'quote', array('customer_id' => 0)); } } } if (class_exists('module_file', false) && module_file::is_plugin_enabled()) { foreach (module_file::get_files(array('owner_id' => $customer_id, 'owner_table' => 'customer')) as $val) { if ($val['customer_id'] && $val['customer_id'] == $customer_id) { update_insert('file_id', $val['file_id'], 'file', array('owner_id' => 0, 'owner_table' => '')); } } } } // finally delete the main customer record // (this is so the above code works with its sql joins) $sql = "DELETE FROM " . _DB_PREFIX . "customer WHERE customer_id = '" . $customer_id . "' LIMIT 1"; query($sql); } } }
</div> <?php } ?> </div> <script type="text/javascript"> set_add_del('quote_tax_holder'); </script> <?php $fieldset_data['elements']['tax'] = array('title' => 'Tax', 'fields' => array(ob_get_clean())); $fieldset_data['elements']['currency'] = array('title' => 'Currency', 'field' => array('type' => 'select', 'options' => get_multiple('currency', '', 'currency_id'), 'name' => 'currency_id', 'value' => $quote['currency_id'], 'options_array_id' => 'code')); // files if ($quote_id > 0) { ob_start(); $files = module_file::get_files(array('quote_id' => $quote_id), true); if (count($files) > 0) { ?> <a href="<?php echo module_file::link_generate(false, array('arguments' => array('quote_id' => $quote['quote_id']), 'data' => array('quote_id' => $quote['quote_id']))); ?> "><?php echo _l('View all %d files in this quote', count($files)); ?> </a> <?php } else { echo _l("This quote has %d files", count($files)); } echo '<br/>';
/** * * This is called from newsletter_queue_manual.php and the cron job (todo) * This will pick the next email in the queue to send and send it. * If there are any problems it will record the problem and return the error to the calling function for display. * TODO: make this support more than one at a time in send_limit (put newsletter_member_id into an array and return that) * * @static * @param $newsletter_id * @param $send_id * @param int $send_limit * @param bool $retry_failures * @return array */ public static function process_send($newsletter_id, $send_id, $send_limit = 1, $retry_failures = false, $retry_pending = false) { $newsletter_id = (int) $newsletter_id; $send_id = (int) $send_id; // todo, make the result friendly for multiple members. $result = array('send_count' => 0, 'send_members' => array()); $send_count = 0; // we pick the next member off the list in this send and send it out. // check the status of this send is still ok to send. $sql = "SELECT `send_id`,`status` FROM `" . _DB_PREFIX . "newsletter_send` WHERE `newsletter_id` = {$newsletter_id} AND `send_id` = {$send_id}"; // $sql .= " AND `status` = " . _NEWSLETTER_STATUS_PENDING ; $status_check = qa1($sql, false); if ($status_check['send_id'] == $send_id) { //$status_check['status']==_NEWSLETTER_STATUS_PENDING && // we have a go for sending to the next member! $sql = "SELECT sm.*, m.* FROM `" . _DB_PREFIX . "newsletter_send_member` sm "; $sql .= " LEFT JOIN `" . _DB_PREFIX . "newsletter_member` m ON sm.newsletter_member_id = m.newsletter_member_id "; // update! we assume all members in the newsletter_send_member table are legit and not unsubscribed. /// this is because we're now removing all unsubscribed members from the mailing list before sending starts. //$sql .= " LEFT JOIN `"._DB_PREFIX."newsletter_blacklist` b ON m.email = b.email "; $sql .= " WHERE sm.`send_id` = {$send_id} "; //sql .= " AND b.newsletter_blacklist_id IS NULL "; // copied from get send members: //$sql .= " AND m.bounce_count < ".(int)module_config::c('newsletter_bounce_threshold',3); //$sql .= " AND m.receive_email = 1"; //$sql .= " AND m.email != ''"; //$sql .= " AND (m.unsubscribe_date IS NULL OR m.unsubscribe_date = '0000-00-00')"; //$sql .= " AND b.email IS NULL"; // todo - instead of this sql query pass this back to our central "get send members" query if ($retry_failures) { $sql .= " AND sm.`status` = " . _NEWSLETTER_STATUS_FAILED . " AND sm.newsletter_member_id > 0"; } else { if ($retry_pending) { $sql .= " AND sm.`status` = " . _NEWSLETTER_STATUS_PENDING . " AND sm.newsletter_member_id > 0"; } else { $sql .= " AND (sm.`status` = " . _NEWSLETTER_STATUS_NEW . " OR sm.`status` = " . _NEWSLETTER_STATUS_PAUSED . ") AND sm.newsletter_member_id > 0"; } } $sql .= " GROUP BY sm.newsletter_member_id "; $send_member_list = query($sql); if (mysql_num_rows($send_member_list) > 0) { while ($send_member = mysql_fetch_assoc($send_member_list)) { if ($send_count >= $send_limit) { break; } // have we already tried sending this member in this loop? if (($retry_failures || $retry_pending) && isset(self::$failed_retries[$send_member['newsletter_member_id']])) { continue; } self::$failed_retries[$send_member['newsletter_member_id']] = true; // a quick lock checking on the member to ensure we don't send it twice // first we check the status of the member. if ($retry_failures || $retry_pending) { } else { // added this in just to be sure we're not sending out duplicates... $sql = "SELECT * FROM `" . _DB_PREFIX . "newsletter_send_member` WHERE (`status` = " . _NEWSLETTER_STATUS_NEW . " OR `status` = " . _NEWSLETTER_STATUS_PAUSED . ") AND `send_id` = {$send_id} AND newsletter_member_id = '" . (int) $send_member['newsletter_member_id'] . "'"; $duplicate_check = qa1($sql); if (empty($duplicate_check)) { // cant find this member, already sent this one then! continue; } } // and we do another check just to make sure we're not sending out duplicates again: $sql = "UPDATE `" . _DB_PREFIX . "newsletter_send_member` SET `status` = " . _NEWSLETTER_STATUS_PENDING . " WHERE `send_id` = {$send_id} AND newsletter_member_id = '" . (int) $send_member['newsletter_member_id'] . "' AND `status` != " . _NEWSLETTER_STATUS_PENDING . ""; query($sql); if ($retry_pending || mysql_affected_rows()) { // we haev a lock on this member! ok to proceed. $member_result['newsletter_member_id'] = (int) $send_member['newsletter_member_id']; // check this member hasn't unsubscribed or any other issues with it... $newsletter = self::get_newsletter($newsletter_id); // both these two do their own "replacey" things. same inside email. $fields = self::get_replace_fields($newsletter_id, $send_id, $send_member['newsletter_member_id'], true); $html = self::render($newsletter_id, $send_id, $send_member['newsletter_member_id'], 'real'); // make any changes here in the send_preview method as well. $email = module_email::new_email(); $email->replace_values = $fields; $email->set_bounce_address($newsletter['bounce_email']); $email->set_from_manual($newsletter['from_email'], $newsletter['from_name']); $email->set_to_manual($send_member['email'], $newsletter['to_name']); $email->set_subject($newsletter['subject']); // do we send images inline? $email->set_html($html); $email->message_id = self::generate_bounce_message_id($newsletter_id, $send_id, $send_member['newsletter_member_id']); // do we attach anything else? $files = module_file::get_files(array('owner_table' => 'newsletter_files', 'owner_id' => $newsletter_id)); foreach ($files as $file_data) { if (is_file($file_data['file_path'])) { $email->AddAttachment($file_data['file_path'], $file_data['file_name']); } } if ($email->send()) { // it worked successfully!! } $member_result['error'] = $email->error_text; $member_result['email'] = $send_member['email']; switch ($email->status) { case _MAIL_STATUS_OVER_QUOTA: // over quota! pause this send until another time. $sql = "UPDATE `" . _DB_PREFIX . "newsletter_send_member` SET `status` = " . _NEWSLETTER_STATUS_PAUSED . ", `sent_time` = 0, `bounce_time` = 0 WHERE `send_id` = {$send_id} AND newsletter_member_id = '" . (int) $send_member['newsletter_member_id'] . "'"; query($sql); break; case _MAIL_STATUS_FAILED: //self::member_email_bounced($send_member['newsletter_member_id'],$send_id); $sql = "UPDATE `" . _DB_PREFIX . "newsletter_send_member` SET `status` = " . _NEWSLETTER_STATUS_FAILED . ", `bounce_time` = '0' WHERE `send_id` = {$send_id} AND newsletter_member_id = '" . (int) $send_member['newsletter_member_id'] . "'"; query($sql); break; case _MAIL_STATUS_SENT: default: // update its status to sent. // do this as a default catch so we don't end up sending duplicates for some weird mail class error. $sql = "UPDATE `" . _DB_PREFIX . "newsletter_send_member` SET `status` = " . _NEWSLETTER_STATUS_SENT . ", `sent_time` = '" . time() . "', `bounce_time` = 0 WHERE `send_id` = {$send_id} AND newsletter_member_id = '" . (int) $send_member['newsletter_member_id'] . "'"; query($sql); break; } $member_result['status'] = $email->status; // so the calling script can handle whatever as well. $result['send_members'][(int) $send_member['newsletter_member_id']] = $member_result; $send_count++; } else { // didn't get a lock on that member for some reason. // probably because the cron job is runing in the background on this same send. } } } else { // no more members left? // update this send to completd. $sql = "UPDATE `" . _DB_PREFIX . "newsletter_send` SET `status` = " . _NEWSLETTER_STATUS_SENT . ", finish_time = '" . time() . "' WHERE `send_id` = {$send_id}"; query($sql); } } $result['send_count'] = $send_count; return $result; }