예제 #1
0
 public function Index()
 {
     AssetLoadManager::register('tableList');
     $t_event_log = new Eventlog();
     $va_events_list = array();
     if (!($ps_search = $this->request->getParameter('search', pString))) {
         $ps_search = $this->request->user->getVar('events_log_search');
     }
     if ($ps_search) {
         $va_events_list = $t_event_log->search($ps_search);
         $this->request->user->setVar('events_log_search', $ps_search);
     }
     $this->view->setVar('events_list', $va_events_list);
     $this->view->setVar('events_list_search', $ps_search);
     $this->render('events_html.php');
 }
예제 #2
0
 public static function authenticate($ps_username, $ps_password = '', $pa_options = null)
 {
     if (!$ps_username) {
         return false;
     }
     $o_auth_config = Configuration::load(Configuration::load()->get('authentication_config'));
     $o_log = new Eventlog();
     // external database config
     $vs_extdb_host = $o_auth_config->get("extdb_host");
     $vs_extdb_username = $o_auth_config->get("extdb_username");
     $vs_extdb_password = $o_auth_config->get("extdb_password");
     $vs_extdb_database = $o_auth_config->get("extdb_database");
     $vs_extdb_db_type = $o_auth_config->get("extdb_db_type");
     $o_ext_db = new Db(null, array('host' => $vs_extdb_host, 'username' => $vs_extdb_username, 'password' => $vs_extdb_password, 'database' => $vs_extdb_database, 'type' => $vs_extdb_db_type, 'persistent_connections' => true), false);
     // couldn't connect to external database
     if (!$o_ext_db->connected()) {
         $o_log->log(array('CODE' => 'LOGF', 'SOURCE' => 'ExternalDBAuthAdapter', 'MESSAGE' => _t('Could not login user %1 using external database because login to external database failed [%2]', $ps_username, $_SERVER['REMOTE_ADDR'])));
         return false;
     }
     $vs_extdb_table = $o_auth_config->get("extdb_table");
     $vs_extdb_username_field = $o_auth_config->get("extdb_username_field");
     $vs_extdb_password_field = $o_auth_config->get("extdb_password_field");
     switch (strtolower($o_auth_config->get("extdb_password_hash_type"))) {
         case 'md5':
             $ps_password_proc = md5($ps_password);
             break;
         case 'sha1':
             $ps_password_proc = sha1($ps_password);
             break;
         default:
             // clear-text
             $ps_password_proc = $ps_password;
             break;
     }
     // Authenticate user against extdb
     $qr_auth = $o_ext_db->query("SELECT * FROM {$vs_extdb_table} WHERE {$vs_extdb_username_field} = ? AND {$vs_extdb_password_field} = ?", array($ps_username, $ps_password_proc));
     if ($qr_auth && $qr_auth->nextRow()) {
         return true;
     }
     return false;
 }
예제 #3
0
 /**
  * 
  * Implements standard username/password and IP-address based user authentication. Applications
  * requiring completely custom authentication methods should override this method. However, most of
  * the time if you need custom authentication you can just create a custom user auth handler class ("username/password" authentication).
  *
  * One clean way to extend Auth is create a sub-class whose constructor calls addUserHandler() and delegates
  * everything else to Auth.
  *
  * @access private 
  * @param array of login options (same as the associative option array in the class constructor)
  */
 public function doAuthentication($pa_options)
 {
     global $AUTH_CURRENT_USER_ID;
     $o_event_log = new Eventlog();
     $vs_app_name = $this->config->get("app_name");
     foreach (array('no_headers', 'dont_redirect_to_login', 'dont_create_new_session', 'dont_redirect_to_welcome', 'user_name', 'password', 'options', 'noPublicUsers', 'dont_redirect', 'no_headers', 'redirect') as $vs_key) {
         if (!isset($pa_options[$vs_key])) {
             $pa_options[$vs_key] = null;
         }
     }
     if (!is_array($pa_options["options"])) {
         $pa_options["options"] = array();
     }
     if ($pa_options["no_headers"]) {
         $pa_options["dont_redirect_to_login"] = true;
         $pa_options["dont_create_new_session"] = true;
         $pa_options["dont_redirect_to_welcome"] = true;
     }
     if ($pa_options["dont_redirect"]) {
         $pa_options["dont_redirect_to_login"] = true;
         $pa_options["dont_redirect_to_welcome"] = true;
     }
     $vb_login_successful = false;
     if (!$pa_options["user_name"]) {
         // no incoming login
         //
         // is a user already logged in?
         //
         if ($vn_user_id = $this->session->getVar($vs_app_name . "_user_id")) {
             // does session have a user attached to it?
             // user is already logged in
             $this->user = new ca_users($vn_user_id);
             // add user object
             if (!$this->user->isActive() || $this->user->numErrors() || $pa_options['noPublicUsers'] && $this->user->isPublicUser()) {
                 // error means user_id in session is invalid
                 $vb_login_successful = false;
             } else {
                 $vb_login_successful = true;
             }
             if ($vb_login_successful) {
                 // Login was successful
                 $this->session->setVar($vs_app_name . "_lastping", time());
                 // set last time we heard from client in session
                 $this->user->setLastPing(time());
                 $AUTH_CURRENT_USER_ID = $vn_user_id;
                 //$this->user->close(); ** will be called externally **
                 return $vb_login_successful;
             }
         }
         if (!$vb_login_successful) {
             $this->user = new ca_users();
             // add user object
             $vs_tmp1 = $vs_tmp2 = null;
             if ($vn_auth_type = $this->user->authenticate($vs_tmp1, $vs_tmp2, $pa_options["options"])) {
                 # error means user_id in session is invalid
                 if ($pa_options['noPublicUsers'] && $this->user->isPublicUser() || !$this->user->isActive()) {
                     $o_event_log->log(array("CODE" => "LOGF", "SOURCE" => "Auth", "MESSAGE" => "Failed login for user id '" . $vn_user_id . "' (" . $_SERVER['REQUEST_URI'] . "); IP=" . $_SERVER["REMOTE_ADDR"] . "; user agent='" . $_SERVER["HTTP_USER_AGENT"] . "'"));
                     $vb_login_successful = false;
                 } else {
                     $vb_login_successful = true;
                     $vn_user_id = $this->user->getUserID();
                 }
             }
             if (!$vb_login_successful) {
                 // throw user to login screen
                 if (!$pa_options["dont_redirect_to_login"]) {
                     $o_event_log->log(array("CODE" => "LOGF", "SOURCE" => "Auth", "MESSAGE" => "Failed login with redirect for user id '" . $vn_user_id . "' (" . $_SERVER['REQUEST_URI'] . "); IP=" . $_SERVER["REMOTE_ADDR"] . "; user agent='" . $_SERVER["HTTP_USER_AGENT"] . "'"));
                     $vs_redirect = $this->getRequestUrl(true);
                     if (strpos($vs_redirect, $this->config->get("auth_login_path") !== -1)) {
                         $vs_redirect = '';
                     } else {
                         $vs_redirect = '?redirect=' . urlencode($vs_redirect);
                     }
                     $this->opo_response->addHeader("Location", $this->getBaseUrlPath() . '/' . $this->getScriptName() . '/' . $this->config->get("auth_login_path") . $vs_redirect);
                 }
                 return false;
             }
         }
     }
     //
     // incoming login
     //
     if ($pa_options["user_name"]) {
         $vb_login_successful = false;
         $this->user = new ca_users();
         if ($vn_auth_type = $this->user->authenticate($pa_options["user_name"], $pa_options["password"], $pa_options["options"])) {
             # error means user_id in session is invalid
             if ($pa_options['noPublicUsers'] && $this->user->isPublicUser() || !$this->user->isActive()) {
                 $vb_login_successful = false;
             } else {
                 $vb_login_successful = true;
                 $vn_user_id = $this->user->getUserID();
             }
         }
     }
     if (!$vb_login_successful) {
         $this->user = null;
         // auth failed
         // throw user to login screen
         if ($pa_options["user_name"]) {
             $o_event_log->log(array("CODE" => "LOGF", "SOURCE" => "Auth", "MESSAGE" => "Failed login for '" . $pa_options["user_name"] . "' (" . $_SERVER['REQUEST_URI'] . "); IP=" . $_SERVER["REMOTE_ADDR"] . "; user agent='" . $_SERVER["HTTP_USER_AGENT"] . "'"));
         }
         if (!$pa_options["dont_redirect_to_login"]) {
             $vs_auth_login_url = $this->getBaseUrlPath() . '/' . $this->getScriptName() . '/' . $this->config->get("auth_login_path");
             $this->opo_response->addHeader("Location", $vs_auth_login_url);
         }
         return false;
     } else {
         $o_event_log->log(array("CODE" => "LOGN", "SOURCE" => "Auth", "MESSAGE" => "Successful login for '" . $pa_options["user_name"] . "'; IP=" . $_SERVER["REMOTE_ADDR"] . "; user agent=" . $_SERVER["HTTP_USER_AGENT"]));
         $this->session->setVar($vs_app_name . "_user_auth_type", $vn_auth_type);
         // type of auth used: 1=username/password; 2=ip-base auth
         $this->session->setVar($vs_app_name . "_user_id", $vn_user_id);
         // auth succeeded; set user_id in session
         $this->session->setVar($vs_app_name . "_logintime", time());
         // also set login time (unix timestamp) in session
         $this->session->setVar($vs_app_name . "_lastping", time());
         $this->session->setVar("screen_width", isset($_REQUEST["_screen_width"]) ? intval($_REQUEST["_screen_width"]) : 0);
         $this->session->setVar("screen_height", isset($_REQUEST["_screen_height"]) ? intval($_REQUEST["_screen_height"]) : 0);
         $this->session->setVar("has_pdf_plugin", isset($_REQUEST["_has_pdf_plugin"]) ? intval($_REQUEST["_has_pdf_plugin"]) : 0);
         $this->user->setVar('last_login', time(), array('volatile' => true));
         $this->user->setLastLogout($this->user->getLastPing(), array('volatile' => true));
         //$this->user->close(); ** will be called externally **
         $AUTH_CURRENT_USER_ID = $vn_user_id;
         if ($pa_options['redirect']) {
             // redirect to specified URL
             $this->opo_response->setRedirect($pa_options['redirect']);
             $this->opo_response->sendResponse();
             exit;
         }
         if (!$pa_options["dont_redirect_to_welcome"]) {
             // redirect to "welcome" page
             $this->opo_response->setRedirect($this->getBaseUrlPath() . '/' . $this->getScriptName() . '/' . $this->config->get("auth_login_welcome_path"));
             $this->opo_response->sendResponse();
             exit;
         }
         return true;
     }
 }
 /**
  * Perform client services-related periodic tasks
  */
 public function hookPeriodicTask(&$pa_params)
 {
     $t_log = new Eventlog();
     $o_db = new Db();
     if (!(bool) $this->opo_config->get('enable_library_services')) {
         return true;
     }
     if ((bool) $this->opo_config->get('enable_object_checkout')) {
         $t_user = new ca_users();
         $t_checkout = new ca_object_checkouts();
         $vs_app_name = $this->opo_config->get('app_display_name');
         $vs_sender_name = $this->opo_library_services_config->get('notification_sender_name');
         $vs_sender_email = $this->opo_library_services_config->get('notification_sender_email');
         if (!is_array($va_administrative_email_addresses = $this->opo_library_services_config->getList('administrative_email_addresses'))) {
             $va_administrative_email_addresses = array();
         }
         // Periodic "coming due" notices
         if ($this->opo_library_services_config->get('send_coming_due_notices') && ($vs_interval = $this->opo_library_services_config->get('coming_due_interval'))) {
             try {
                 $va_items_by_user = ca_object_checkouts::getItemsDueWithin($vs_interval, array('groupBy' => 'user_id', 'template' => $this->opo_library_services_config->get('coming_due_item_display_template'), 'notificationInterval' => $this->opo_library_services_config->get('coming_due_notification_interval')));
                 foreach ($va_items_by_user as $vn_user_id => $va_items_for_user) {
                     if ($t_user->load($vn_user_id)) {
                         if ($vs_user_email = $t_user->get('email')) {
                             $vs_subject = _t('Notice of items coming due for return');
                             if (caSendMessageUsingView(null, $vs_user_email, $vs_sender_email, "[{$vs_app_name}] {$vs_subject}", "library_coming_due.tpl", array('subject' => $vs_subject, 'from_user_id' => $vn_user_id, 'sender_name' => $vs_sender_name, 'sender_email' => $vs_sender_email, 'sent_on' => time(), 'items' => $va_items_for_user), null, $va_administrative_email_addresses)) {
                                 // mark record
                                 foreach ($va_items_for_user as $va_item) {
                                     if ($t_checkout->load($va_item['checkout_id'])) {
                                         $t_checkout->setMode(ACCESS_WRITE);
                                         $t_checkout->set('last_sent_coming_due_email', _t('now'));
                                         $t_checkout->update();
                                         if ($t_checkout->numErrors()) {
                                             $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Could not mark checkout coming due message sent time because update failed: %1', join("; ", $t_checkout->getErrors())), 'SOURCE' => 'libraryServicesPlugin->hookPeriodicTask'));
                                         }
                                     } else {
                                         $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Could not mark checkout coming due message sent time because checkout id %1 was not found', $va_item['checkout_id']), 'SOURCE' => 'libraryServicesPlugin->hookPeriodicTask'));
                                     }
                                 }
                             }
                         } else {
                             // no email
                             $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('No email address set for user %1 (%2)', $t_user->get('user_name'), trim($t_user->get('fname') . ' ' . $t_user->get('lname'))), 'SOURCE' => 'libraryServicesPlugin->hookPeriodicTask'));
                         }
                     } else {
                         // invalid user
                         $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('User id %1 does not exist', $vn_user_id), 'SOURCE' => 'libraryServicesPlugin->hookPeriodicTask'));
                     }
                 }
             } catch (Exception $e) {
                 $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Invalid interval (%1) specified for coming due notices', $vs_interval), 'SOURCE' => 'libraryServicesPlugin->hookPeriodicTask'));
             }
         }
         // Periodic overdue notices
         if ($this->opo_library_services_config->get('send_overdue_notices')) {
             try {
                 $va_items_by_user = ca_object_checkouts::getOverdueItems(array('groupBy' => 'user_id', 'template' => $this->opo_library_services_config->get('overdue_item_display_template'), 'notificationInterval' => $this->opo_library_services_config->get('overdue_notification_interval')));
                 foreach ($va_items_by_user as $vn_user_id => $va_items_for_user) {
                     if ($t_user->load($vn_user_id)) {
                         if ($vs_user_email = $t_user->get('email')) {
                             $vs_subject = _t('Notice of overdue items');
                             if (caSendMessageUsingView(null, $vs_user_email, $vs_sender_email, "[{$vs_app_name}] {$vs_subject}", "library_overdue.tpl", array('subject' => $vs_subject, 'from_user_id' => $vn_user_id, 'sender_name' => $vs_sender_name, 'sender_email' => $vs_sender_email, 'sent_on' => time(), 'items' => $va_items_for_user), null, $va_administrative_email_addresses)) {
                                 // mark record
                                 foreach ($va_items_for_user as $va_item) {
                                     if ($t_checkout->load($va_item['checkout_id'])) {
                                         $t_checkout->setMode(ACCESS_WRITE);
                                         $t_checkout->set('last_sent_overdue_email', _t('now'));
                                         $t_checkout->update();
                                         if ($t_checkout->numErrors()) {
                                             $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Could not mark checkout overdue message sent time because update failed: %1', join("; ", $t_checkout->getErrors())), 'SOURCE' => 'libraryServicesPlugin->hookPeriodicTask'));
                                         }
                                     } else {
                                         $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Could not mark checkout overdue message sent time because checkout id %1 was not found', $va_item['checkout_id']), 'SOURCE' => 'libraryServicesPlugin->hookPeriodicTask'));
                                     }
                                 }
                             }
                         } else {
                             // no email
                             $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('No email address set for user %1 (%2)', $t_user->get('user_name'), trim($t_user->get('fname') . ' ' . $t_user->get('lname'))), 'SOURCE' => 'libraryServicesPlugin->hookPeriodicTask'));
                         }
                     } else {
                         // invalid user
                         $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('User id %1 does not exist', $vn_user_id), 'SOURCE' => 'libraryServicesPlugin->hookPeriodicTask'));
                     }
                 }
             } catch (Exception $e) {
                 $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Failed to get overdue list'), 'SOURCE' => 'libraryServicesPlugin->hookPeriodicTask'));
             }
         }
         // Notice when reservation becomes available
         if ($this->opo_library_services_config->get('send_reservation_available_notices')) {
             try {
                 $va_items_by_user = ca_object_checkouts::getReservedAvailableItems(array('groupBy' => 'user_id', 'template' => $this->opo_library_services_config->get('overdue_item_display_template'), 'notificationInterval' => $this->opo_library_services_config->get('reservation_available_notification_interval')));
                 foreach ($va_items_by_user as $vn_user_id => $va_items_for_user) {
                     if ($t_user->load($vn_user_id)) {
                         if ($vs_user_email = $t_user->get('email')) {
                             $vs_subject = _t('Notice of reserved available items');
                             if (caSendMessageUsingView(null, $vs_user_email, $vs_sender_email, "[{$vs_app_name}] {$vs_subject}", "library_reservation_available.tpl", array('subject' => $vs_subject, 'from_user_id' => $vn_user_id, 'sender_name' => $vs_sender_name, 'sender_email' => $vs_sender_email, 'sent_on' => time(), 'items' => $va_items_for_user), null, $va_administrative_email_addresses)) {
                                 // mark record
                                 foreach ($va_items_for_user as $va_item) {
                                     if ($t_checkout->load($va_item['checkout_id'])) {
                                         $t_checkout->setMode(ACCESS_WRITE);
                                         $t_checkout->set('last_reservation_available_email', _t('now'));
                                         $t_checkout->update();
                                         if ($t_checkout->numErrors()) {
                                             $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Could not mark reserved available message sent time because update failed: %1', join("; ", $t_checkout->getErrors())), 'SOURCE' => 'libraryServicesPlugin->hookPeriodicTask'));
                                         }
                                     } else {
                                         $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Could not mark reserved available message sent time because checkout id %1 was not found', $va_item['checkout_id']), 'SOURCE' => 'libraryServicesPlugin->hookPeriodicTask'));
                                     }
                                 }
                             }
                         } else {
                             // no email
                             $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('No email address set for user %1 (%2)', $t_user->get('user_name'), trim($t_user->get('fname') . ' ' . $t_user->get('lname'))), 'SOURCE' => 'libraryServicesPlugin->hookPeriodicTask'));
                         }
                     } else {
                         // invalid user
                         $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('User id %1 does not exist', $vn_user_id), 'SOURCE' => 'libraryServicesPlugin->hookPeriodicTask'));
                     }
                 }
             } catch (Exception $e) {
                 $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Failed to get reserved available list'), 'SOURCE' => 'libraryServicesPlugin->hookPeriodicTask'));
             }
         }
     }
     return true;
 }
예제 #5
0
 public function process($pa_parameters)
 {
     $va_files = $pa_parameters["FILES"];
     $vn_files_sent = 0;
     $table = $pa_parameters["TABLE"];
     $field = $pa_parameters["FIELD"];
     $pk = $pa_parameters["PK"];
     $id = $pa_parameters["PK_VAL"];
     $o_eventlog = new Eventlog();
     $va_report = array('errors' => array(), 'notes' => array());
     #
     # Connect to FTP
     #
     $r_ftp = ftp_connect($pa_parameters["MIRROR_INFO"]["hostname"]);
     if (!$r_ftp) {
         $this->error->setError(580, "Could not connect to FTP server at " . $pa_parameters["MIRROR_INFO"]["hostname"], "ftpmirror->process()");
         return 0;
     }
     if (!ftp_login($r_ftp, $pa_parameters["MIRROR_INFO"]["username"], $pa_parameters["MIRROR_INFO"]["password"])) {
         $this->error->setError(581, "Could not login to FTP server at " . $pa_parameters["MIRROR_INFO"]["hostname"], "ftpmirror->process()");
         return 0;
     }
     if ($pa_parameters["MIRROR_INFO"]["passive"]) {
         ftp_pasv($r_ftp, 1);
     }
     foreach ($va_files as $va_file_info) {
         $vs_file_path = $va_file_info["FILE_PATH"];
         if ($pa_parameters["DELETE"]) {
             #
             # Delete file from remote server
             #
             $vs_remote_path = join("/", array($pa_parameters["MIRROR_INFO"]["directory"], $va_file_info["HASH"], $va_file_info["FILENAME"]));
             if ($this->debug) {
                 print "DEBUG: DELETING {$vs_remote_path} FROM remote server\n";
             }
             ftp_delete($r_ftp, $vs_remote_path);
             $va_report['notes'][] = _t("Deleted %1 from remote server", $vs_remote_path);
             $vn_files_sent++;
         } else {
             #
             # Upload file to remote server
             #
             if (file_exists($vs_file_path)) {
                 $vs_remote_path = join("/", array($pa_parameters["MIRROR_INFO"]["directory"], $va_file_info["HASH"], $va_file_info["FILENAME"]));
                 $va_pieces = explode("/", $vs_remote_path);
                 #
                 # Create directories
                 #
                 array_pop($va_pieces);
                 # get rid of file name
                 $vn_num_pieces = sizeof($va_pieces);
                 for ($vn_i = 1; $vn_i <= $vn_num_pieces; $vn_i++) {
                     $vs_dir = join("/", array_slice($va_pieces, 0, $vn_i));
                     if ($this->debug) {
                         print "DEBUG: CREATING DIRECTORY {$vs_dir}\n";
                     }
                     @ftp_mkdir($r_ftp, $vs_dir);
                 }
                 if ($this->debug) {
                     print "DEBUG: SENDING {$vs_file_path} TO remote " . $vs_remote_path . "\n";
                 }
                 $vs_remote_path = str_replace('//', '/', $vs_remote_path);
                 ftp_put($r_ftp, $vs_remote_path, $vs_file_path, FTP_BINARY);
                 $va_report['notes'][] = _t("Sent %1 to remote server at %2", $vs_file_path, $vs_remote_path);
                 $vn_files_sent++;
             } else {
                 # bad table name
                 $this->error->setError(570, "File to mirror '{$vs_file_path}' does not exist", "ftpmirror->process()");
             }
         }
     }
     ftp_close($r_ftp);
     if ($vn_files_sent < sizeof($va_files)) {
         // partial mirror
         $vn_mirror_code = "PARTIAL";
     } else {
         if ($vn_files_sent == 0) {
             // failed mirror
             $vn_mirror_code = "FAIL";
         } else {
             // successful mirror
             $vn_mirror_code = "SUCCESS";
         }
     }
     #
     # Update record
     #
     $o_dm =& Datamodel::load();
     if ($table_obj = $o_dm->getTableInstance($table)) {
         if ($table_obj->hasField($field)) {
             if ($table_obj->load($id)) {
                 $md = $table_obj->get($field);
                 if (!is_array($md["MIRROR_STATUS"])) {
                     $md["MIRROR_STATUS"] = array();
                 }
                 $md["MIRROR_STATUS"][$pa_parameters["MIRROR"]] = $vn_mirror_code;
                 $table_obj->setMediaInfo($field, $md);
                 $table_obj->setMode(ACCESS_WRITE);
                 $table_obj->update();
                 if ($table_obj->numErrors()) {
                     $o_eventlog->log(array("CODE" => "ERR", "SOURCE" => "ftpmirror->process", "MESSAGE" => "Could not update mirror status for mirror '" . $pa_parameters["MIRROR"] . "' on '{$table}'; row_id={$id}\n"));
                     $va_report['errors'][] = _t("Could not update mirror status for mirror '%1' on '%2'; row_id=%3", $pa_parameters["MIRROR"], $table, $id);
                 }
             }
         }
     }
     return $va_report;
 }
예제 #6
0
/**
 * Sends mail using server settings specified in app.conf/global.conf
 *
 * Parameters are:
 *
 * 	$pa_to: 	Email address(es) of message recipients. Can be a string containing a single email address or
 *				an associative array with keys set to multiple addresses and corresponding values optionally set to
 *				a human-readable recipient name.
 *	$pa_from:	The email address of the message sender. Can be a string containing a single email address or
 *				an associative array with keys set to multiple addresses and corresponding values optionally set to
 *				a human-readable sender name.
 *	$ps_subject:	The subject line of the message
 *	$ps_body_text:	The text of the message				(optional)
 *	$ps_html_text:	The HTML-format text of the message (optional)
 * 	$pa_cc: 	Email address(es) of cc'ed message recipients. Can be a string containing a single email address or
 *				an associative array with keys set to multiple addresses and corresponding values optionally set to
 *				a human-readable recipient name. (optional)
 * 	$pa_bcc: 	Email address(es) of bcc'ed message recipients. Can be a string containing a single email address or
 *				an associative array with keys set to multiple addresses and corresponding values optionally set to
 *				a human-readable recipient name. (optional)
 * 	$pa_attachment: 	array containing file path, name and mimetype of file to attach.
 *				keys are "path", "name", "mimetype"
 *
 * While both $ps_body_text and $ps_html_text are optional, at least one should be set and both can be set for a 
 * combination text and HTML email
 */
function caSendmail($pa_to, $pa_from, $ps_subject, $ps_body_text, $ps_body_html = '', $pa_cc = null, $pa_bcc = null, $pa_attachment = null)
{
    $o_config = Configuration::load();
    $o_log = new Eventlog();
    $va_smtp_config = array();
    if ($o_config->get('smtp_auth')) {
        $vs_smtp_auth = $o_config->get('smtp_auth');
    } else {
        $vs_smtp_auth = '';
    }
    if ($o_config->get('smtp_username')) {
        $vs_smtp_uname = $o_config->get('smtp_username');
        $vs_smtp_auth = 'login';
    } else {
        $vs_smtp_uname = '';
    }
    if ($o_config->get('smtp_password')) {
        $vs_smtp_pw = $o_config->get('smtp_password');
        $vs_smtp_auth = 'login';
    } else {
        $vs_smtp_pw = '';
    }
    $va_smtp_config = array('username' => $vs_smtp_uname, 'password' => $vs_smtp_pw);
    if ($vs_smtp_auth) {
        $va_smtp_config['auth'] = $vs_smtp_auth;
    }
    if ($vs_ssl = $o_config->get('smtp_ssl')) {
        $va_smtp_config['ssl'] = $vs_ssl;
    }
    if ($vs_port = $o_config->get('smtp_port')) {
        $va_smtp_config['port'] = $vs_port;
    }
    try {
        if ($o_config->get('smtp_use_sendmail_transport')) {
            $vo_tr = new Zend_Mail_Transport_Sendmail($o_config->get('smtp_server'), $va_smtp_config);
        } else {
            $vo_tr = new Zend_Mail_Transport_Smtp($o_config->get('smtp_server'), $va_smtp_config);
        }
        $o_mail = new Zend_Mail('UTF-8');
        if (is_array($pa_from)) {
            foreach ($pa_from as $vs_from_email => $vs_from_name) {
                $o_mail->setFrom($vs_from_email, $vs_from_name);
            }
        } else {
            $o_mail->setFrom($pa_from);
        }
        if (!is_array($pa_to)) {
            $pa_to = array($pa_to => $pa_to);
        }
        foreach ($pa_to as $vs_to_email => $vs_to_name) {
            if (is_numeric($vs_to_email)) {
                $o_mail->addTo($vs_to_name, $vs_to_name);
            } else {
                $o_mail->addTo($vs_to_email, $vs_to_name);
            }
        }
        if (is_array($pa_cc) && sizeof($pa_cc)) {
            foreach ($pa_cc as $vs_to_email => $vs_to_name) {
                if (is_numeric($vs_to_email)) {
                    $o_mail->addCc($vs_to_name, $vs_to_name);
                } else {
                    $o_mail->addCc($vs_to_email, $vs_to_name);
                }
            }
        }
        if (is_array($pa_bcc) && sizeof($pa_bcc)) {
            foreach ($pa_bcc as $vs_to_email => $vs_to_name) {
                if (is_numeric($vs_to_email)) {
                    $o_mail->addBcc($vs_to_name, $vs_to_name);
                } else {
                    $o_mail->addBcc($vs_to_email, $vs_to_name);
                }
            }
        }
        if (is_array($pa_attachment) && $pa_attachment["path"]) {
            $ps_attachment_url = $pa_attachment["path"];
            # --- only attach media if it is less than 50MB
            if (filesize($ps_attachment_url) < 419430400) {
                $vs_file_contents = file_get_contents($ps_attachment_url);
                $o_attachment = $o_mail->createAttachment($vs_file_contents);
                if ($pa_attachment["name"]) {
                    $o_attachment->filename = $pa_attachment["name"];
                }
                if ($pa_attachment["mimetype"]) {
                    $o_attachment->type = $pa_attachment["mimetype"];
                }
            }
        }
        $o_mail->setSubject($ps_subject);
        if ($ps_body_text) {
            $o_mail->setBodyText($ps_body_text);
        }
        if ($ps_body_html) {
            $o_mail->setBodyHtml($ps_body_html);
        }
        $o_mail->send($vo_tr);
        $o_log->log(array('CODE' => 'SYS', 'SOURCE' => 'Registration', 'MESSAGE' => _t('Registration confirmation email was sent to %1', join(';', array_keys($pa_to)))));
        return true;
    } catch (Exception $e) {
        $o_log->log(array('CODE' => 'ERR', 'SOURCE' => 'Registration', 'MESSAGE' => _t('Could not send registration confirmation email to %1: %2', join(';', array_keys($pa_to)), $e->getMessage())));
        return false;
    }
}
예제 #7
0
 /**
  * Tweet on save of item
  */
 public function hookSaveItem(&$pa_params)
 {
     $t_subject = $pa_params['instance'];
     // get instance from params
     $bitly = new bitly('collectiveaccess', 'R_8a0ecd6ea746c58f787d6769329b9976');
     // check access
     $va_access_values = $this->opo_config->getList($t_subject->tableName() . '_tweet_when_access');
     if (is_array($va_access_values) && sizeof($va_access_values)) {
         if (!in_array($t_subject->get('access'), $va_access_values)) {
             // Skip record because it is not publicly accessible
             return $pa_params;
         }
     }
     // check update threshold (prevents repeated tweeting when a record is repeatedly saved over a short period of time)
     if (($vn_threshold = $this->opo_config->get($t_subject->tableName() . "_tweet_update_threshold")) <= 0) {
         // seconds
         $vn_threshold = 3600;
         // default to one hour if no threshold is specified
     }
     $vb_access_changed = $t_subject->get('access') != $this->opn_old_access_value;
     $this->opn_old_access_value = null;
     if (!$vb_access_changed && time() - $this->opn_last_update_timestamp < $vn_threshold) {
         return $pa_params;
     }
     // Get Twitter token. If it doesn't exist silently skip posting.
     if ($o_token = @unserialize(file_get_contents(__CA_APP_DIR__ . '/tmp/twitter.token'))) {
         try {
             $o_twitter = new Zend_Service_Twitter(array('consumerKey' => $this->opo_config->get('consumer_key'), 'consumerSecret' => $this->opo_config->get('consumer_secret'), 'username' => $this->opo_config->get('twitter_username'), 'accessToken' => $o_token));
             // Post to Twitter
             $vn_id = $t_subject->getPrimaryKey();
             $vs_url = $this->opo_config->get($t_subject->tableName() . '_public_url') . $vn_id;
             $vs_url_bitly = $bitly->shorten($vs_url);
             $vs_tweet = $this->opo_config->get($pa_params['is_insert'] ? $t_subject->tableName() . '_new_message' : $t_subject->tableName() . '_updated_message');
             if ($vs_tweet) {
                 // substitute tags
                 $vs_tweet = caProcessTemplate($vs_tweet, array('BITLY_URL' => $vs_url_bitly, 'URL' => $vs_url, 'ID' => $vn_id), array('getFrom' => $t_subject, 'delimiter' => ', '));
                 if (mb_strlen($vs_tweet) > 140) {
                     $vs_tweet = mb_substr($vs_tweet, 0, 140);
                 }
                 $o_response = $o_twitter->status->update($vs_tweet);
             }
         } catch (Exception $e) {
             // Don't post error to user - Twitter failing is not a critical error
             // But let's put it in the event log so you have some chance of knowing what's going on
             //print "Post to Twitter failed: ".$e->getMessage();
             $o_log = new Eventlog();
             $o_log->log(array('SOURCE' => 'twitter plugin', 'MESSAGE' => _t('Post to Twitter failed: %1', $e->getMessage()), 'CODE' => 'ERR'));
         }
     }
     return $pa_params;
 }
예제 #8
0
 /**
  * Do authentification against an external database (creates user based on directory 
  * information and config preferences in authentication.conf)
  * @param string $ps_username username
  * @param string $ps_password password
  */
 private function authenticateExtDB($ps_username = "", $ps_password = "")
 {
     $o_log = new Eventlog();
     // external database config
     $vs_extdb_host = $this->opo_auth_config->get("extdb_host");
     $vs_extdb_username = $this->opo_auth_config->get("extdb_username");
     $vs_extdb_password = $this->opo_auth_config->get("extdb_password");
     $vs_extdb_database = $this->opo_auth_config->get("extdb_database");
     $vs_extdb_db_type = $this->opo_auth_config->get("extdb_db_type");
     $o_ext_db = new Db(null, array('host' => $vs_extdb_host, 'username' => $vs_extdb_username, 'password' => $vs_extdb_password, 'database' => $vs_extdb_database, 'type' => $vs_extdb_db_type, 'persistent_connections' => true), false);
     if ($o_ext_db->connected()) {
         $vs_extdb_table = $this->opo_auth_config->get("extdb_table");
         $vs_extdb_username_field = $this->opo_auth_config->get("extdb_username_field");
         $vs_extdb_password_field = $this->opo_auth_config->get("extdb_password_field");
         switch (strtolower($this->opo_auth_config->get("extdb_password_hash_type"))) {
             case 'md5':
                 $ps_password_proc = md5($ps_password);
                 break;
             case 'sha1':
                 $ps_password_proc = sha1($ps_password);
                 break;
             default:
                 $ps_password_proc = $ps_password;
                 break;
         }
         // Authenticate user against extdb
         $qr_auth = $o_ext_db->query("\n\t\t\t\tSELECT * FROM {$vs_extdb_table} WHERE {$vs_extdb_username_field} = ? AND {$vs_extdb_password_field} = ?\n\t\t\t", array($ps_username, $ps_password_proc));
         if ($qr_auth && $qr_auth->nextRow()) {
             if (!$this->load(array("user_name" => $ps_username))) {
                 // first user login, authentication via extdb successful
                 // Set username/password
                 $this->set("user_name", $ps_username);
                 $this->set("password", $ps_password);
                 // Determine value for ca_users.active
                 $vn_active = (int) $this->opo_auth_config->get('extdb_default_active');
                 $va_extdb_active_field_map = $this->opo_auth_config->getAssoc('extdb_active_field_map');
                 if (($vs_extdb_active_field = $this->opo_auth_config->get('extdb_active_field')) && is_array($va_extdb_active_field_map)) {
                     if (isset($va_extdb_active_field_map[$vs_active_val = $qr_auth->get($vs_extdb_active_field)])) {
                         $vn_active = (int) $va_extdb_active_field_map[$vs_active_val];
                     }
                 }
                 $this->set("active", $vn_active);
                 // Determine value for ca_users.user_class
                 $vs_extdb_access_value = strtolower($this->opo_auth_config->get('extdb_default_access'));
                 $va_extdb_access_field_map = $this->opo_auth_config->getAssoc('extdb_access_field_map');
                 if (($vs_extdb_access_field = $this->opo_auth_config->get('extdb_access_field')) && is_array($va_extdb_access_field_map)) {
                     if (isset($va_extdb_access_field_map[$vs_access_val = $qr_auth->get($vs_extdb_access_field)])) {
                         $vs_extdb_access_value = strtolower($va_extdb_access_field_map[$vs_access_val]);
                     }
                 }
                 switch ($vs_extdb_access_value) {
                     case 'public':
                         $vn_user_class = 1;
                         break;
                     case 'full':
                         $vn_user_class = 0;
                         break;
                     default:
                         // Can't log in - no access
                         $o_log->log(array('CODE' => 'LOGF', 'SOURCE' => 'ca_users/extdb', 'MESSAGE' => _t('Could not login user %1 after authentication from external database because user class was not set.', $ps_username)));
                         return false;
                         break;
                 }
                 $this->set('userclass', $vn_user_class);
                 // map fields
                 if (is_array($va_extdb_user_field_map = $this->opo_auth_config->getAssoc('extdb_user_field_map'))) {
                     foreach ($va_extdb_user_field_map as $vs_extdb_field => $vs_ca_field) {
                         $this->set($vs_ca_field, $qr_auth->get($vs_extdb_field));
                     }
                 }
                 $vn_mode = $this->getMode();
                 $this->setMode(ACCESS_WRITE);
                 $this->insert();
                 if (!$this->getPrimaryKey()) {
                     // log record creation failed
                     $o_log->log(array('CODE' => 'LOGF', 'SOURCE' => 'ca_users/extdb', 'MESSAGE' => _t('Could not login user %1 after authentication from external database because creation of user record failed: %2 [%3]', $ps_username, join("; ", $this->getErrors()), $_SERVER['REMOTE_ADDR'])));
                     return false;
                 }
                 // map preferences
                 if (is_array($va_extdb_user_pref_map = $this->opo_auth_config->getAssoc('extdb_user_pref_map'))) {
                     foreach ($va_extdb_user_pref_map as $vs_extdb_field => $vs_ca_pref) {
                         $this->setPreference($vs_ca_pref, $qr_auth->get($vs_extdb_field));
                     }
                 }
                 $this->update();
                 // set user roles
                 $va_extdb_user_roles = $this->opo_auth_config->getAssoc('extdb_default_roles');
                 $va_extdb_roles_field_map = $this->opo_auth_config->getAssoc('extdb_roles_field_map');
                 if (($vs_extdb_roles_field = $this->opo_auth_config->get('extdb_roles_field')) && is_array($va_extdb_roles_field_map)) {
                     if (isset($va_extdb_roles_field_map[$vs_roles_val = $qr_auth->get($vs_extdb_roles_field)])) {
                         $va_extdb_user_roles = $va_extdb_roles_field_map[$vs_roles_val];
                     }
                 }
                 if (!is_array($va_extdb_user_roles)) {
                     $va_extdb_user_roles = array();
                 }
                 if (sizeof($va_extdb_user_roles)) {
                     $this->addRoles($va_extdb_user_roles);
                 }
                 // set user groups
                 $va_extdb_user_groups = $this->opo_auth_config->getAssoc('extdb_default_groups');
                 $va_extdb_groups_field_map = $this->opo_auth_config->getAssoc('extdb_groups_field_map');
                 if (($vs_extdb_groups_field = $this->opo_auth_config->get('extdb_groups_field')) && is_array($va_extdb_groups_field_map)) {
                     if (isset($va_extdb_groups_field_map[$vs_groups_val = $qr_auth->get($vs_extdb_groups_field)])) {
                         $va_extdb_user_groups = $va_extdb_groups_field_map[$vs_groups_val];
                     }
                 }
                 if (!is_array($va_extdb_user_groups)) {
                     $va_extdb_user_groups = array();
                 }
                 if (sizeof($va_extdb_user_groups)) {
                     $this->addToGroups($va_extdb_user_groups);
                 }
                 // restore mode
                 $this->setMode($vn_mode);
                 // TODO: log user creation
                 $o_log->log(array('CODE' => 'LOGN', 'SOURCE' => 'ca_users/extdb', 'MESSAGE' => _t('Created new login for user %1 after authentication from external database [%2]', $ps_username, $_SERVER['REMOTE_ADDR'])));
             }
             return true;
         } else {
             // authentication failed
             //$o_log->log(array('CODE' => 'LOGF', 'SOURCE' => 'ca_users/extdb', 'MESSAGE' => _t('Could not login user %1 using external database because external authentication failed [%2]', $ps_username, $_SERVER['REMOTE_ADDR'])));
             return false;
         }
     } else {
         // couldn't connect to external database
         $o_log->log(array('CODE' => 'LOGF', 'SOURCE' => 'ca_users/extdb', 'MESSAGE' => _t('Could not login user %1 using external database because login to external database failed [%2]', $ps_username, $_SERVER['REMOTE_ADDR'])));
         return false;
     }
 }
예제 #9
0
 /**
  * @return string Unique request token. The token can be used on subsequent calls to fetch information about the replication request
  */
 public function initiateReplication($ps_filepath, $pa_data, $pa_options = null)
 {
     $o_client = $this->getClient();
     $pa_target_options = $this->opa_target_info['options'];
     try {
         if (!$o_client) {
             throw new VimeoAPIException(_t("Initial connection to Vimeo failed. Did you authorize CollectiveAccess to use your Vimeo account? Enable the 'vimeo' application plugin and navigate to Manage > Vimeo integration to do so."));
         }
         // upload video to vimeo, set properties afterwards
         if ($vs_video_id = $o_client->upload($ps_filepath)) {
             // generic options (provided by media replication layer)
             $o_client->call('vimeo.videos.setTitle', array('title' => $pa_data['title'], 'video_id' => $vs_video_id));
             $o_client->call('vimeo.videos.setDescription', array('description' => $pa_data['description'], 'video_id' => $vs_video_id));
             if (isset($pa_data['tags'])) {
                 $o_client->call('vimeo.videos.addTags', array('tags' => $pa_data['tags'], 'video_id' => $vs_video_id));
             }
             // custom options for vimeo
             // Vimeo's privacy settings are string values. possible values are anybody, nobody, contacts, users, password, or disable.
             $vs_privacy_setting = caGetOption('privacy', $pa_target_options, 'nobody');
             // this, however, is 1 or 0
             $vn_dl_privacy = caGetOption('downloadPrivacy', $pa_target_options, 0);
             // by, by-sa, by-nd, by-nc, by-nc-sa, or by-nc-nd. Set to 0 for no CC license.
             $vs_license = caGetOption('license', $pa_target_options, 0);
             $o_client->call('vimeo.videos.setPrivacy', array('privacy' => $vs_privacy_setting, 'video_id' => $vs_video_id));
             $o_client->call('vimeo.videos.setDownloadPrivacy', array('download' => $vn_dl_privacy, 'video_id' => $vs_video_id));
             $o_client->call('vimeo.videos.setLicense', array('license' => $vs_license, 'video_id' => $vs_video_id));
             if (isset($pa_target_options['channel'])) {
                 $o_client->call('vimeo.channels.addVideo', array('channel_id' => $pa_target_options['channel'], 'video_id' => $vs_video_id));
             }
         } else {
             // upload() and all other phpVimeo methods throw their
             // own exceptions if something goes wrong, except in this case
             throw new VimeoAPIException(_t("File for replication doesn't exist"));
         }
     } catch (VimeoAPIException $e) {
         // Let's put the error in the event log so you have some chance of knowing what's going on
         $o_log = new Eventlog();
         $o_log->log(array('SOURCE' => 'Vimeo replication plugin', 'MESSAGE' => _t('Upload to Vimeo failed. Code: %1, Message: %2', $e->getCode(), $e->getMessage()), 'CODE' => 'ERR'));
         // if we get a "Permission denied" exception, it's likely the OAuth privileges
         // have been revoked by the user. In that case we can toss our access token
         if ($e->getCode() == 401) {
             if (file_exists(__CA_APP_DIR__ . '/tmp/vimeo.token')) {
                 @unlink(__CA_APP_DIR__ . '/tmp/vimeo.token');
             }
         }
         return false;
     }
     return $this->info['NAME'] . "://" . $vs_video_id;
 }
예제 #10
0
 /**
  * @param RequestHTTP $po_request
  * @param null|array $pa_options
  *		progressCallback =
  *		reportCallback =
  *		sendMail =
  *		log = log directory path
  *		logLevel = KLogger constant for minimum log level to record. Default is KLogger::INFO. Constants are, in descending order of shrillness:
  *			KLogger::EMERG = Emergency messages (system is unusable)
  *			KLogger::ALERT = Alert messages (action must be taken immediately)
  *			KLogger::CRIT = Critical conditions
  *			KLogger::ERR = Error conditions
  *			KLogger::WARN = Warnings
  *			KLogger::NOTICE = Notices (normal but significant conditions)
  *			KLogger::INFO = Informational messages
  *			KLogger::DEBUG = Debugging messages
  * @return array
  */
 public static function importMediaFromDirectory($po_request, $pa_options = null)
 {
     global $g_ui_locale_id;
     $vs_log_dir = caGetOption('log', $pa_options, __CA_APP_DIR__ . "/log");
     $vs_log_level = caGetOption('logLevel', $pa_options, "INFO");
     if (!is_writeable($vs_log_dir)) {
         $vs_log_dir = caGetTempDirPath();
     }
     $vn_log_level = BatchProcessor::_logLevelStringToNumber($vs_log_level);
     $o_log = new KLogger($vs_log_dir, $vn_log_level);
     $vs_import_target = caGetOption('importTarget', $pa_options, 'ca_objects');
     $t_instance = $po_request->getAppDatamodel()->getInstance($vs_import_target);
     $o_eventlog = new Eventlog();
     $t_set = new ca_sets();
     $va_notices = $va_errors = array();
     $vb_we_set_transaction = false;
     $o_trans = isset($pa_options['transaction']) && $pa_options['transaction'] ? $pa_options['transaction'] : null;
     if (!$o_trans) {
         $vb_we_set_transaction = true;
         $o_trans = new Transaction($t_set->getDb());
     }
     $o_batch_log = new Batchlog(array('user_id' => $po_request->getUserID(), 'batch_type' => 'MI', 'table_num' => (int) $t_instance->tableNum(), 'notes' => '', 'transaction' => $o_trans));
     if (!is_dir($pa_options['importFromDirectory'])) {
         $o_eventlog->log(array("CODE" => 'ERR', "SOURCE" => "mediaImport", "MESSAGE" => $vs_msg = _t("Specified import directory '%1' is invalid", $pa_options['importFromDirectory'])));
         $o_log->logError($vs_msg);
         return null;
     }
     $vs_batch_media_import_root_directory = $po_request->config->get('batch_media_import_root_directory');
     if (!preg_match("!^{$vs_batch_media_import_root_directory}!", $pa_options['importFromDirectory'])) {
         $o_eventlog->log(array("CODE" => 'ERR', "SOURCE" => "mediaImport", "MESSAGE" => $vs_msg = _t("Specified import directory '%1' is invalid", $pa_options['importFromDirectory'])));
         $o_log->logError($vs_msg);
         return null;
     }
     if (preg_match("!\\.\\./!", $pa_options['importFromDirectory'])) {
         $o_eventlog->log(array("CODE" => 'ERR', "SOURCE" => "mediaImport", "MESSAGE" => $vs_msg = _t("Specified import directory '%1' is invalid", $pa_options['importFromDirectory'])));
         $o_log->logError($vs_msg);
         return null;
     }
     $vb_include_subdirectories = (bool) $pa_options['includeSubDirectories'];
     $vb_delete_media_on_import = (bool) $pa_options['deleteMediaOnImport'];
     $vs_import_mode = $pa_options['importMode'];
     $vs_match_mode = $pa_options['matchMode'];
     $vn_type_id = $pa_options[$vs_import_target . '_type_id'];
     $vn_rep_type_id = $pa_options['ca_object_representations_type_id'];
     $va_limit_matching_to_type_ids = $pa_options[$vs_import_target . '_limit_matching_to_type_ids'];
     $vn_access = $pa_options[$vs_import_target . '_access'];
     $vn_object_representation_access = $pa_options['ca_object_representations_access'];
     $vn_status = $pa_options[$vs_import_target . '_status'];
     $vn_object_representation_status = $pa_options['ca_object_representations_status'];
     $vn_rel_type_id = isset($pa_options[$vs_import_target . '_representation_relationship_type']) ? $pa_options[$vs_import_target . '_representation_relationship_type'] : null;
     $vn_mapping_id = $pa_options[$vs_import_target . '_mapping_id'];
     $vn_object_representation_mapping_id = $pa_options['ca_object_representations_mapping_id'];
     $vs_idno_mode = $pa_options['idnoMode'];
     $vs_idno = $pa_options['idno'];
     $vs_representation_idno_mode = $pa_options['representationIdnoMode'];
     $vs_representation_idno = $pa_options['representation_idno'];
     $vs_set_mode = $pa_options['setMode'];
     $vs_set_create_name = $pa_options['setCreateName'];
     $vn_set_id = $pa_options['set_id'];
     $vn_locale_id = $pa_options['locale_id'];
     $vs_skip_file_list = $pa_options['skipFileList'];
     $vs_skip_file_list = $pa_options['skipFileList'];
     $vb_allow_duplicate_media = $pa_options['allowDuplicateMedia'];
     $va_relationship_type_id_for = array();
     if (is_array($va_create_relationship_for = $pa_options['create_relationship_for'])) {
         foreach ($va_create_relationship_for as $vs_rel_table) {
             $va_relationship_type_id_for[$vs_rel_table] = $pa_options['relationship_type_id_for_' . $vs_rel_table];
         }
     }
     if (!$vn_locale_id) {
         $vn_locale_id = $g_ui_locale_id;
     }
     $va_files_to_process = caGetDirectoryContentsAsList($pa_options['importFromDirectory'], $vb_include_subdirectories);
     $o_log->logInfo(_t('Found %1 files in directory \'%2\'', sizeof($va_files_to_process), $pa_options['importFromDirectory']));
     if ($vs_set_mode == 'add') {
         $t_set->load($vn_set_id);
     } else {
         if ($vs_set_mode == 'create' && $vs_set_create_name) {
             $va_set_ids = $t_set->getSets(array('user_id' => $po_request->getUserID(), 'table' => $t_instance->tableName(), 'access' => __CA_SET_EDIT_ACCESS__, 'setIDsOnly' => true, 'name' => $vs_set_create_name));
             $vn_set_id = null;
             if (is_array($va_set_ids) && sizeof($va_set_ids) > 0) {
                 $vn_possible_set_id = array_shift($va_set_ids);
                 if ($t_set->load($vn_possible_set_id)) {
                     $vn_set_id = $t_set->getPrimaryKey();
                 }
             } else {
                 $vs_set_code = mb_substr(preg_replace("![^A-Za-z0-9_\\-]+!", "_", $vs_set_create_name), 0, 100);
                 if ($t_set->load(array('set_code' => $vs_set_code))) {
                     $vn_set_id = $t_set->getPrimaryKey();
                 }
             }
             if (!$t_set->getPrimaryKey()) {
                 $t_set->setMode(ACCESS_WRITE);
                 $t_set->set('user_id', $po_request->getUserID());
                 $t_set->set('type_id', $po_request->config->get('ca_sets_default_type'));
                 $t_set->set('table_num', $t_instance->tableNum());
                 $t_set->set('set_code', $vs_set_code);
                 $t_set->insert();
                 if ($t_set->numErrors()) {
                     $va_notices['create_set'] = array('idno' => '', 'label' => _t('Create set %1', $vs_set_create_name), 'message' => $vs_msg = _t('Failed to create set %1: %2', $vs_set_create_name, join("; ", $t_set->getErrors())), 'status' => 'SET ERROR');
                     $o_log->logError($vs_msg);
                 } else {
                     $t_set->addLabel(array('name' => $vs_set_create_name), $vn_locale_id, null, true);
                     if ($t_set->numErrors()) {
                         $va_notices['add_set_label'] = array('idno' => '', 'label' => _t('Add label to set %1', $vs_set_create_name), 'message' => $vs_msg = _t('Failed to add label to set: %1', join("; ", $t_set->getErrors())), 'status' => 'SET ERROR');
                         $o_log->logError($vs_msg);
                     }
                     $vn_set_id = $t_set->getPrimaryKey();
                 }
             }
         } else {
             $vn_set_id = null;
             // no set
         }
     }
     if ($t_set->getPrimaryKey() && !$t_set->haveAccessToSet($po_request->getUserID(), __CA_SET_EDIT_ACCESS__)) {
         $va_notices['set_access'] = array('idno' => '', 'label' => _t('You do not have access to set %1', $vs_set_create_name), 'message' => $vs_msg = _t('Cannot add to set %1 because you do not have edit access', $vs_set_create_name), 'status' => 'SET ERROR');
         $o_log->logError($vs_msg);
         $vn_set_id = null;
         $t_set = new ca_sets();
     }
     $vn_num_items = sizeof($va_files_to_process);
     // Get list of regex packages that user can use to extract object idno's from filenames
     $va_regex_list = caBatchGetMediaFilenameToIdnoRegexList(array('log' => $o_log));
     // Get list of replacements that user can use to transform file names to match object idnos
     $va_replacements_list = caBatchGetMediaFilenameReplacementRegexList(array('log' => $o_log));
     // Get list of files (or file name patterns) to skip
     $va_skip_list = preg_split("![\r\n]+!", $vs_skip_file_list);
     foreach ($va_skip_list as $vn_i => $vs_skip) {
         if (!strlen($va_skip_list[$vn_i] = trim($vs_skip))) {
             unset($va_skip_list[$vn_i]);
         }
     }
     $vn_c = 0;
     $vn_start_time = time();
     $va_report = array();
     foreach ($va_files_to_process as $vs_file) {
         $va_tmp = explode("/", $vs_file);
         $f = array_pop($va_tmp);
         $d = array_pop($va_tmp);
         array_push($va_tmp, $d);
         $vs_directory = join("/", $va_tmp);
         // Skip file names using $vs_skip_file_list
         if (BatchProcessor::_skipFile($f, $va_skip_list)) {
             $o_log->logInfo(_t('Skipped file %1 because it was on the skipped files list', $f));
             continue;
         }
         $vs_relative_directory = preg_replace("!{$vs_batch_media_import_root_directory}[/]*!", "", $vs_directory);
         // does representation already exist?
         if (!$vb_allow_duplicate_media && ($t_dupe = ca_object_representations::mediaExists($vs_file))) {
             $va_notices[$vs_relative_directory . '/' . $f] = array('idno' => '', 'label' => $f, 'message' => $vs_msg = _t('Skipped %1 from %2 because it already exists %3', $f, $vs_relative_directory, caEditorLink($po_request, _t('(view)'), 'button', 'ca_object_representations', $t_dupe->getPrimaryKey())), 'status' => 'SKIPPED');
             $o_log->logInfo($vs_msg);
             continue;
         }
         $t_instance = $po_request->getAppDatamodel()->getInstance($vs_import_target, false);
         $t_instance->setTransaction($o_trans);
         $vs_modified_filename = $f;
         $va_extracted_idnos_from_filename = array();
         if (in_array($vs_import_mode, array('TRY_TO_MATCH', 'ALWAYS_MATCH')) || is_array($va_create_relationship_for) && sizeof($va_create_relationship_for)) {
             foreach ($va_regex_list as $vs_regex_name => $va_regex_info) {
                 $o_log->logDebug(_t("Processing mediaFilenameToObjectIdnoRegexes entry %1", $vs_regex_name));
                 foreach ($va_regex_info['regexes'] as $vs_regex) {
                     switch ($vs_match_mode) {
                         case 'DIRECTORY_NAME':
                             $va_names_to_match = array($d);
                             $o_log->logDebug(_t("Trying to match on directory '%1'", $d));
                             break;
                         case 'FILE_AND_DIRECTORY_NAMES':
                             $va_names_to_match = array($f, $d);
                             $o_log->logDebug(_t("Trying to match on directory '%1' and file name '%2'", $d, $f));
                             break;
                         default:
                         case 'FILE_NAME':
                             $va_names_to_match = array($f);
                             $o_log->logDebug(_t("Trying to match on file name '%1'", $f));
                             break;
                     }
                     // are there any replacements? if so, try to match each element in $va_names_to_match AND all results of the replacements
                     if (is_array($va_replacements_list) && sizeof($va_replacements_list) > 0) {
                         $va_names_to_match_copy = $va_names_to_match;
                         foreach ($va_names_to_match_copy as $vs_name) {
                             foreach ($va_replacements_list as $vs_replacement_code => $va_replacement) {
                                 if (isset($va_replacement['search']) && is_array($va_replacement['search'])) {
                                     $va_replace = caGetOption('replace', $va_replacement);
                                     $va_search = array();
                                     foreach ($va_replacement['search'] as $vs_search) {
                                         $va_search[] = '!' . $vs_search . '!';
                                     }
                                     $vs_replacement_result = @preg_replace($va_search, $va_replace, $vs_name);
                                     if (is_null($vs_replacement_result)) {
                                         $o_log->logError(_t("There was an error in preg_replace while processing replacement %1.", $vs_replacement_code));
                                     }
                                     if ($vs_replacement_result && strlen($vs_replacement_result) > 0) {
                                         $o_log->logDebug(_t("The result for replacement with code %1 applied to value '%2' is '%3' and was added to the list of file names used for matching.", $vs_replacement_code, $vs_name, $vs_replacement_result));
                                         $va_names_to_match[] = $vs_replacement_result;
                                     }
                                 } else {
                                     $o_log->logDebug(_t("Skipped replacement %1 because no search expression was defined.", $vs_replacement_code));
                                 }
                             }
                         }
                     }
                     $o_log->logDebug("Names to match: " . print_r($va_names_to_match, true));
                     foreach ($va_names_to_match as $vs_match_name) {
                         if (preg_match('!' . $vs_regex . '!', $vs_match_name, $va_matches)) {
                             $o_log->logDebug(_t("Matched name %1 on regex %2", $vs_match_name, $vs_regex));
                             if (!$vs_idno || strlen($va_matches[1]) < strlen($vs_idno)) {
                                 $vs_idno = $va_matches[1];
                             }
                             if (!$vs_modified_filename || strlen($vs_modified_filename) > strlen($va_matches[1])) {
                                 $vs_modified_filename = $va_matches[1];
                             }
                             $va_extracted_idnos_from_filename[] = $va_matches[1];
                             if (in_array($vs_import_mode, array('TRY_TO_MATCH', 'ALWAYS_MATCH'))) {
                                 if (!is_array($va_fields_to_match_on = $po_request->config->getList('batch_media_import_match_on')) || !sizeof($va_fields_to_match_on)) {
                                     $batch_media_import_match_on = array('idno');
                                 }
                                 $vs_bool = 'OR';
                                 $va_values = array();
                                 foreach ($va_fields_to_match_on as $vs_fld) {
                                     if (in_array($vs_fld, array('preferred_labels', 'nonpreferred_labels'))) {
                                         $va_values[$vs_fld] = array($vs_fld => array('name' => $va_matches[1]));
                                     } else {
                                         $va_values[$vs_fld] = $va_matches[1];
                                     }
                                 }
                                 if (is_array($va_limit_matching_to_type_ids) && sizeof($va_limit_matching_to_type_ids) > 0) {
                                     $va_values['type_id'] = $va_limit_matching_to_type_ids;
                                     $vs_bool = 'AND';
                                 }
                                 $o_log->logDebug("Trying to find records using boolean {$vs_bool} and values " . print_r($va_values, true));
                                 if (class_exists($vs_import_target) && ($vn_id = $vs_import_target::find($va_values, array('returnAs' => 'firstId', 'boolean' => $vs_bool)))) {
                                     if ($t_instance->load($vn_id)) {
                                         $va_notices[$vs_relative_directory . '/' . $vs_match_name . '_match'] = array('idno' => $t_instance->get($t_instance->getProperty('ID_NUMBERING_ID_FIELD')), 'label' => $t_instance->getLabelForDisplay(), 'message' => $vs_msg = _t('Matched media %1 from %2 to %3 using expression "%4"', $f, $vs_relative_directory, caGetTableDisplayName($vs_import_target, false), $va_regex_info['displayName']), 'status' => 'MATCHED');
                                         $o_log->logInfo($vs_msg);
                                     }
                                     break 3;
                                 }
                             }
                         } else {
                             $o_log->logDebug(_t("Couldn't match name %1 on regex %2", $vs_match_name, $vs_regex));
                         }
                     }
                 }
             }
         }
         if (!$t_instance->getPrimaryKey()) {
             // Use filename as idno if all else fails
             if ($t_instance->load(array('idno' => $f, 'deleted' => 0))) {
                 $va_notices[$vs_relative_directory . '/' . $f . '_match'] = array('idno' => $t_instance->get($t_instance->getProperty('ID_NUMBERING_ID_FIELD')), 'label' => $t_instance->getLabelForDisplay(), 'message' => $vs_msg = _t('Matched media %1 from %2 to %3 using filename', $f, $vs_relative_directory, caGetTableDisplayName($vs_import_target, false)), 'status' => 'MATCHED');
                 $o_log->logInfo($vs_msg);
             }
         }
         switch ($vs_representation_idno_mode) {
             case 'filename':
                 // use the filename as identifier
                 $vs_rep_idno = $f;
                 break;
             case 'filename_no_ext':
                 // use filename without extension as identifier
                 $vs_rep_idno = preg_replace('/\\.[^.\\s]{3,4}$/', '', $f);
                 break;
             case 'directory_and_filename':
                 // use the directory + filename as identifier
                 $vs_rep_idno = $d . '/' . $f;
                 break;
             default:
                 // use idno from form
                 $vs_rep_idno = $vs_representation_idno;
                 break;
         }
         $t_new_rep = null;
         if ($t_instance->getPrimaryKey() && $t_instance instanceof RepresentableBaseModel) {
             // found existing object
             $t_instance->setMode(ACCESS_WRITE);
             $t_new_rep = $t_instance->addRepresentation($vs_directory . '/' . $f, $vn_rep_type_id, $vn_locale_id, $vn_object_representation_status, $vn_object_representation_access, false, array('idno' => $vs_rep_idno), array('original_filename' => $f, 'returnRepresentation' => true, 'type_id' => $vn_rel_type_id));
             if ($t_instance->numErrors()) {
                 $o_eventlog->log(array("CODE" => 'ERR', "SOURCE" => "mediaImport", "MESSAGE" => _t("Error importing {$f} from {$vs_directory}: %1", join('; ', $t_instance->getErrors()))));
                 $va_errors[$vs_relative_directory . '/' . $f] = array('idno' => $t_instance->get($t_instance->getProperty('ID_NUMBERING_ID_FIELD')), 'label' => $t_instance->getLabelForDisplay(), 'errors' => $t_instance->errors(), 'message' => $vs_msg = _t("Error importing %1 from %2: %3", $f, $vs_relative_directory, join('; ', $t_instance->getErrors())), 'status' => 'ERROR');
                 $o_log->logError($vs_msg);
                 $o_trans->rollback();
                 continue;
             } else {
                 if ($vb_delete_media_on_import) {
                     @unlink($vs_directory . '/' . $f);
                 }
             }
         } else {
             // should we create new record?
             if (in_array($vs_import_mode, array('TRY_TO_MATCH', 'DONT_MATCH'))) {
                 $t_instance->setMode(ACCESS_WRITE);
                 $t_instance->set('type_id', $vn_type_id);
                 $t_instance->set('locale_id', $vn_locale_id);
                 $t_instance->set('status', $vn_status);
                 $t_instance->set('access', $vn_access);
                 // for places, take first hierarchy we can find. in most setups there is but one. we might wanna make this configurable via setup screen at some point
                 if ($t_instance->hasField('hierarchy_id')) {
                     $va_hierarchies = $t_instance->getHierarchyList();
                     reset($va_hierarchies);
                     $vn_hierarchy_id = key($va_hierarchies);
                     $t_instance->set('hierarchy_id', $vn_hierarchy_id);
                 }
                 switch ($vs_idno_mode) {
                     case 'filename':
                         // use the filename as identifier
                         $t_instance->set('idno', $f);
                         break;
                     case 'filename_no_ext':
                         // use filename without extension as identifier
                         $f_no_ext = preg_replace('/\\.[^.\\s]{3,4}$/', '', $f);
                         $t_instance->set('idno', $f_no_ext);
                         break;
                     case 'directory_and_filename':
                         // use the directory + filename as identifier
                         $t_instance->set('idno', $d . '/' . $f);
                         break;
                     default:
                         // Calculate identifier using numbering plugin
                         $o_numbering_plugin = $t_instance->getIDNoPlugInInstance();
                         if (!($vs_sep = $o_numbering_plugin->getSeparator())) {
                             $vs_sep = '';
                         }
                         if (!is_array($va_idno_values = $o_numbering_plugin->htmlFormValuesAsArray('idno', null, false, false, true))) {
                             $va_idno_values = array();
                         }
                         $t_instance->set('idno', join($vs_sep, $va_idno_values));
                         // true=always set serial values, even if they already have a value; this let's us use the original pattern while replacing the serial value every time through
                         break;
                 }
                 $t_instance->insert();
                 if ($t_instance->numErrors()) {
                     $o_eventlog->log(array("CODE" => 'ERR', "SOURCE" => "mediaImport", "MESSAGE" => _t("Error creating new record while importing %1 from %2: %3", $f, $vs_relative_directory, join('; ', $t_instance->getErrors()))));
                     $va_errors[$vs_relative_directory . '/' . $f] = array('idno' => $t_instance->get($t_instance->getProperty('ID_NUMBERING_ID_FIELD')), 'label' => $t_instance->getLabelForDisplay(), 'errors' => $t_instance->errors(), 'message' => $vs_msg = _t("Error creating new record while importing %1 from %2: %3", $f, $vs_relative_directory, join('; ', $t_instance->getErrors())), 'status' => 'ERROR');
                     $o_log->logError($vs_msg);
                     $o_trans->rollback();
                     continue;
                 }
                 if ($t_instance->tableName() == 'ca_entities') {
                     // entity labels deserve special treatment
                     $t_instance->addLabel(array('surname' => $f), $vn_locale_id, null, true);
                 } else {
                     $t_instance->addLabel(array($t_instance->getLabelDisplayField() => $f), $vn_locale_id, null, true);
                 }
                 if ($t_instance->numErrors()) {
                     $o_eventlog->log(array("CODE" => 'ERR', "SOURCE" => "mediaImport", "MESSAGE" => _t("Error creating record label while importing %1 from %2: %3", $f, $vs_relative_directory, join('; ', $t_instance->getErrors()))));
                     $va_errors[$vs_relative_directory . '/' . $f] = array('idno' => $t_instance->get($t_instance->getProperty('ID_NUMBERING_ID_FIELD')), 'label' => $t_instance->getLabelForDisplay(), 'errors' => $t_instance->errors(), 'message' => $vs_msg = _t("Error creating record label while importing %1 from %2: %3", $f, $vs_relative_directory, join('; ', $t_instance->getErrors())), 'status' => 'ERROR');
                     $o_log->logError($vs_msg);
                     $o_trans->rollback();
                     continue;
                 }
                 $t_new_rep = $t_instance->addRepresentation($vs_directory . '/' . $f, $vn_rep_type_id, $vn_locale_id, $vn_object_representation_status, $vn_object_representation_access, true, array('idno' => $vs_rep_idno), array('original_filename' => $f, 'returnRepresentation' => true, 'type_id' => $vn_rel_type_id));
                 if ($t_instance->numErrors()) {
                     $o_eventlog->log(array("CODE" => 'ERR', "SOURCE" => "mediaImport", "MESSAGE" => _t("Error importing %1 from %2: ", $f, $vs_relative_directory, join('; ', $t_instance->getErrors()))));
                     $va_errors[$vs_relative_directory . '/' . $f] = array('idno' => $t_instance->get($t_instance->getProperty('ID_NUMBERING_ID_FIELD')), 'label' => $t_instance->getLabelForDisplay(), 'errors' => $t_instance->errors(), 'message' => $vs_msg = _t("Error importing %1 from %2: %3", $f, $vs_relative_directory, join('; ', $t_instance->getErrors())), 'status' => 'ERROR');
                     $o_log->logError($vs_msg);
                     $o_trans->rollback();
                     continue;
                 } else {
                     if ($vb_delete_media_on_import) {
                         @unlink($vs_directory . '/' . $f);
                     }
                 }
             }
         }
         if ($t_instance->getPrimaryKey()) {
             // Perform import of embedded metadata (if required)
             if ($vn_mapping_id) {
                 ca_data_importers::importDataFromSource($vs_directory . '/' . $f, $vn_mapping_id, array('logLevel' => $vs_log_level, 'format' => 'exif', 'forceImportForPrimaryKeys' => array($t_instance->getPrimaryKey(), 'transaction' => $o_trans)));
             }
             if ($vn_object_representation_mapping_id) {
                 ca_data_importers::importDataFromSource($vs_directory . '/' . $f, $vn_object_representation_mapping_id, array('logLevel' => $vs_log_level, 'format' => 'exif', 'forceImportForPrimaryKeys' => array($t_new_rep->getPrimaryKey()), 'transaction' => $o_trans));
             }
             $va_notices[$t_instance->getPrimaryKey()] = array('idno' => $t_instance->get($t_instance->getProperty('ID_NUMBERING_ID_FIELD')), 'label' => $t_instance->getLabelForDisplay(), 'message' => $vs_msg = _t('Imported %1 as %2', $f, $t_instance->get($t_instance->getProperty('ID_NUMBERING_ID_FIELD'))), 'status' => 'SUCCESS');
             $o_log->logInfo($vs_msg);
             if ($vn_set_id) {
                 $t_set->addItem($t_instance->getPrimaryKey(), null, $po_request->getUserID());
             }
             $o_batch_log->addItem($t_instance->getPrimaryKey(), $t_instance->errors());
             // Create relationships?
             if (is_array($va_create_relationship_for) && sizeof($va_create_relationship_for) && is_array($va_extracted_idnos_from_filename) && sizeof($va_extracted_idnos_from_filename)) {
                 foreach ($va_extracted_idnos_from_filename as $vs_idno) {
                     foreach ($va_create_relationship_for as $vs_rel_table) {
                         if (!isset($va_relationship_type_id_for[$vs_rel_table]) || !$va_relationship_type_id_for[$vs_rel_table]) {
                             continue;
                         }
                         $t_rel = $t_instance->getAppDatamodel()->getInstanceByTableName($vs_rel_table);
                         if ($t_rel->load(array($t_rel->getProperty('ID_NUMBERING_ID_FIELD') => $vs_idno))) {
                             $t_instance->addRelationship($vs_rel_table, $t_rel->getPrimaryKey(), $va_relationship_type_id_for[$vs_rel_table]);
                             if (!$t_instance->numErrors()) {
                                 $va_notices[$t_instance->getPrimaryKey() . '_rel'] = array('idno' => $t_instance->get($t_instance->getProperty('ID_NUMBERING_ID_FIELD')), 'label' => $vs_label = $t_instance->getLabelForDisplay(), 'message' => $vs_msg = _t('Added relationship between <em>%1</em> and %2 <em>%3</em>', $vs_label, $t_rel->getProperty('NAME_SINGULAR'), $t_rel->getLabelForDisplay()), 'status' => 'RELATED');
                                 $o_log->logInfo($vs_msg);
                             } else {
                                 $va_notices[$t_instance->getPrimaryKey()] = array('idno' => $t_instance->get($t_instance->getProperty('ID_NUMBERING_ID_FIELD')), 'label' => $vs_label = $t_instance->getLabelForDisplay(), 'message' => $vs_msg = _t('Could not add relationship between <em>%1</em> and %2 <em>%3</em>: %4', $vs_label, $t_rel->getProperty('NAME_SINGULAR'), $t_rel->getLabelForDisplay(), join("; ", $t_instance->getErrors())), 'status' => 'ERROR');
                                 $o_log->logError($vs_msg);
                             }
                         }
                     }
                 }
             }
         } else {
             $va_notices[$vs_relative_directory . '/' . $f] = array('idno' => '', 'label' => $f, 'message' => $vs_msg = $vs_import_mode == 'ALWAYS_MATCH' ? _t('Skipped %1 from %2 because it could not be matched', $f, $vs_relative_directory) : _t('Skipped %1 from %2', $f, $vs_relative_directory), 'status' => 'SKIPPED');
             $o_log->logInfo($vs_msg);
         }
         if (isset($pa_options['progressCallback']) && ($ps_callback = $pa_options['progressCallback'])) {
             $ps_callback($po_request, $vn_c, $vn_num_items, _t("[%3/%4] Processing %1 (%3)", caTruncateStringWithEllipsis($vs_relative_directory, 20) . '/' . caTruncateStringWithEllipsis($f, 30), $t_instance->get($t_instance->getProperty('ID_NUMBERING_ID_FIELD')), $vn_c, $vn_num_items), $t_new_rep, time() - $vn_start_time, memory_get_usage(true), $vn_c, sizeof($va_errors));
         }
         $vn_c++;
     }
     if (isset($pa_options['progressCallback']) && ($ps_callback = $pa_options['progressCallback'])) {
         $ps_callback($po_request, $vn_num_items, $vn_num_items, _t("Processing completed"), null, time() - $vn_start_time, memory_get_usage(true), $vn_c, sizeof($va_errors));
     }
     $vn_elapsed_time = time() - $vn_start_time;
     if (isset($pa_options['reportCallback']) && ($ps_callback = $pa_options['reportCallback'])) {
         $va_general = array('elapsedTime' => $vn_elapsed_time, 'numErrors' => sizeof($va_errors), 'numProcessed' => $vn_c, 'batchSize' => $vn_num_items, 'table' => $t_instance->tableName(), 'set_id' => $t_set->getPrimaryKey(), 'setName' => $t_set->getLabelForDisplay());
         $ps_callback($po_request, $va_general, $va_notices, $va_errors);
     }
     $o_batch_log->close();
     if ($vb_we_set_transaction) {
         if (sizeof($va_errors) > 0) {
             $o_trans->rollback();
         } else {
             $o_trans->commit();
         }
     }
     $vs_set_name = $t_set->getLabelForDisplay();
     $vs_started_on = caGetLocalizedDate($vn_start_time);
     if (isset($pa_options['sendMail']) && $pa_options['sendMail']) {
         if ($vs_email = trim($po_request->user->get('email'))) {
             caSendMessageUsingView($po_request, array($vs_email => $po_request->user->get('fname') . ' ' . $po_request->user->get('lname')), __CA_ADMIN_EMAIL__, _t('[%1] Batch media import completed', $po_request->config->get('app_display_name')), 'batch_media_import_completed.tpl', array('notices' => $va_notices, 'errors' => $va_errors, 'directory' => $vs_relative_directory, 'numErrors' => sizeof($va_errors), 'numProcessed' => $vn_c, 'subjectNameSingular' => _t('file'), 'subjectNamePlural' => _t('files'), 'startedOn' => $vs_started_on, 'completedOn' => caGetLocalizedDate(time()), 'setName' => $vn_set_id ? $vs_set_name : null, 'elapsedTime' => caFormatInterval($vn_elapsed_time)));
         }
     }
     if (isset($pa_options['sendSMS']) && $pa_options['sendSMS']) {
         SMS::send($po_request->getUserID(), _t("[%1] Media import processing for directory %2 with %3 %4 begun at %5 is complete", $po_request->config->get('app_display_name'), $vs_relative_directory, $vn_num_items, $vn_num_items == 1 ? _t('file') : _t('files'), $vs_started_on));
     }
     $o_log->logInfo(_t("Media import processing for directory %1 with %2 %3 begun at %4 is complete", $vs_relative_directory, $vn_num_items, $vn_num_items == 1 ? _t('file') : _t('files')));
     return array('errors' => $va_errors, 'notices' => $va_notices, 'processing_time' => caFormatInterval($vn_elapsed_time));
 }
예제 #11
0
 /**
  * Generates display summary of record data based upon a bundle display for print (PDF)
  *
  * @param array $pa_options Array of options passed through to _initView 
  */
 public function PrintSummary($pa_options = null)
 {
     require_once __CA_LIB_DIR__ . "/core/Print/html2pdf/html2pdf.class.php";
     JavascriptLoadManager::register('tableList');
     list($vn_subject_id, $t_subject) = $this->_initView($pa_options);
     //
     // Is record of correct type?
     //
     $va_restrict_to_types = null;
     if ($t_subject->getAppConfig()->get('perform_type_access_checking')) {
         $va_restrict_to_types = caGetTypeRestrictionsForUser($this->ops_table_name, array('access' => __CA_BUNDLE_ACCESS_READONLY__));
     }
     if (is_array($va_restrict_to_types) && !in_array($t_subject->get('type_id'), $va_restrict_to_types)) {
         $this->response->setRedirect($this->request->config->get('error_display_url') . '/n/2560?r=' . urlencode($this->request->getFullUrlPath()));
         return;
     }
     //
     // Does user have access to row?
     //
     if ($t_subject->getAppConfig()->get('perform_item_level_access_checking')) {
         if ($t_subject->checkACLAccessForUser($this->request->user) == __CA_ACL_NO_ACCESS__) {
             $this->response->setRedirect($this->request->config->get('error_display_url') . '/n/2580?r=' . urlencode($this->request->getFullUrlPath()));
             return;
         }
     }
     $t_display = new ca_bundle_displays();
     $va_displays = $t_display->getBundleDisplays(array('table' => $t_subject->tableNum(), 'user_id' => $this->request->getUserID(), 'access' => __CA_BUNDLE_DISPLAY_READ_ACCESS__, 'restrictToTypes' => array($t_subject->getTypeID())));
     if (!($vn_display_id = $this->request->getParameter('display_id', pInteger)) || !isset($va_displays[$vn_display_id])) {
         if (!($vn_display_id = $this->request->user->getVar($t_subject->tableName() . '_summary_display_id')) || !isset($va_displays[$vn_display_id])) {
             $va_tmp = array_keys($va_displays);
             $vn_display_id = $va_tmp[0];
         }
     }
     $this->view->setVar('t_display', $t_display);
     $this->view->setVar('bundle_displays', $va_displays);
     // Check validity and access of specified display
     if ($t_display->load($vn_display_id) && $t_display->haveAccessToDisplay($this->request->getUserID(), __CA_BUNDLE_DISPLAY_READ_ACCESS__)) {
         $this->view->setVar('display_id', $vn_display_id);
         $va_placements = $t_display->getPlacements(array('returnAllAvailableIfEmpty' => true, 'table' => $t_subject->tableNum(), 'user_id' => $this->request->getUserID(), 'access' => __CA_BUNDLE_DISPLAY_READ_ACCESS__, 'no_tooltips' => true, 'format' => 'simple', 'settingsOnly' => true));
         $va_display_list = array();
         foreach ($va_placements as $vn_placement_id => $va_display_item) {
             $va_settings = caUnserializeForDatabase($va_display_item['settings']);
             // get column header text
             $vs_header = $va_display_item['display'];
             if (isset($va_settings['label']) && is_array($va_settings['label'])) {
                 if ($vs_tmp = array_shift(caExtractValuesByUserLocale(array($va_settings['label'])))) {
                     $vs_header = $vs_tmp;
                 }
             }
             $va_display_list[$vn_placement_id] = array('placement_id' => $vn_placement_id, 'bundle_name' => $va_display_item['bundle_name'], 'display' => $vs_header, 'settings' => $va_settings);
         }
         $this->view->setVar('placements', $va_display_list);
         $this->request->user->setVar($t_subject->tableName() . '_summary_display_id', $vn_display_id);
         $vs_format = $this->request->config->get("summary_print_format");
     } else {
         $this->view->setVar('display_id', null);
         $this->view->setVar('placements', array());
     }
     try {
         $vs_content = $this->render('print_summary_html.php');
         $vo_html2pdf = new HTML2PDF('P', $vs_format, 'en');
         $vo_html2pdf->setDefaultFont("dejavusans");
         $vo_html2pdf->WriteHTML($vs_content);
         $vo_html2pdf->Output('summary.pdf');
         $vb_printed_properly = true;
     } catch (Exception $e) {
         $vb_printed_properly = false;
         $o_event_log = new Eventlog();
         $o_event_log->log(array('CODE' => 'DEBG', 'MESSAGE' => $vs_msg = _t("Could not generate PDF: %1", preg_replace('![^A-Za-z0-9 \\-\\?\\/\\.]+!', ' ', $e->getMessage())), 'SOURCE' => 'BaseEditorController->PrintSummary()'));
         $this->postError(3100, $vs_msg, "BaseEditorController->PrintSummary()");
     }
 }
예제 #12
0
 public function process($pa_parameters)
 {
     $va_files = $pa_parameters["FILES"];
     $vn_files_sent = 0;
     $table = $pa_parameters["TABLE"];
     $field = $pa_parameters["FIELD"];
     $pk = $pa_parameters["PK"];
     $id = $pa_parameters["PK_VAL"];
     $o_eventlog = new Eventlog();
     $va_report = array('errors' => array(), 'notes' => array());
     // AWS access info
     $access_key_id = $pa_parameters["MIRROR_INFO"]["access_key_id"];
     $secret_access_key = $pa_parameters["MIRROR_INFO"]["secret_access_key"];
     if (!defined('awsAccessKey')) {
         define('awsAccessKey', $access_key_id);
     }
     if (!defined('awsSecretKey')) {
         define('awsSecretKey', $secret_access_key);
     }
     #
     # Connect to AS3
     #
     $s3 = new S3(awsAccessKey, awsSecretKey);
     foreach ($va_files as $va_file_info) {
         $vs_file_path = $va_file_info["FILE_PATH"];
         if ($pa_parameters["DELETE"]) {
             #
             # Delete file from remote server
             #
             $bucketName = $pa_parameters["MIRROR_INFO"]["bucket"];
             $deleteFile = $va_file_info["FILENAME"];
             if ($this->debug) {
                 print "DEBUG: DELETING {$deleteFile} FROM remote server\n";
             }
             $s3->deleteObject($bucketName, baseName($deleteFile));
             $va_report['notes'][] = _t("Deleted %1 from remote server", $deleteFile);
             $vn_files_sent++;
         } else {
             #
             # Upload file to remote server
             #
             if (file_exists($vs_file_path)) {
                 #
                 # Create BUCKET
                 #
                 $bucketName = $pa_parameters["MIRROR_INFO"]["bucket"];
                 if ($this->debug) {
                     print "DEBUG: CREATING BUCKET {$bucketName}\n";
                 }
                 $s3->putBucket($bucketName, S3::ACL_PUBLIC_READ);
                 $putFile = $va_file_info["HASH"] . "/" . $va_file_info["FILENAME"];
                 # fake directories for AS3
                 if ($this->debug) {
                     print "DEBUG: SENDING {$putFile} TO remote " . $bucketName . "\n";
                 }
                 $s3->putObjectFile($vs_file_path, $bucketName, $putFile, S3::ACL_PUBLIC_READ);
                 $va_report['notes'][] = _t("Sent %1 to remote %2", $putFile, $bucketName);
                 $vn_files_sent++;
             } else {
                 # bad table name
                 $this->error->setError(570, "File to mirror '{$vs_file_path}' does not exist", "as3mirror->process()");
             }
         }
     }
     if ($vn_files_sent < sizeof($va_files)) {
         // partial mirror
         $vn_mirror_code = "PARTIAL";
     } else {
         if ($vn_files_sent == 0) {
             // failed mirror
             $vn_mirror_code = "FAIL";
         } else {
             // successful mirror
             $vn_mirror_code = "SUCCESS";
         }
     }
     #
     # Update record
     #
     $o_dm =& Datamodel::load();
     if ($table_obj = $o_dm->getTableInstance($table)) {
         if ($table_obj->hasField($field)) {
             if ($table_obj->load($id)) {
                 $md = $table_obj->get($field);
                 if (!is_array($md["MIRROR_STATUS"])) {
                     $md["MIRROR_STATUS"] = array();
                 }
                 $md["MIRROR_STATUS"][$pa_parameters["MIRROR"]] = $vn_mirror_code;
                 $table_obj->setMediaInfo($field, $md);
                 $table_obj->setMode(ACCESS_WRITE);
                 $table_obj->update();
                 if ($table_obj->numErrors()) {
                     $o_eventlog->log(array("CODE" => "ERR", "SOURCE" => "as3mirror->process", "MESSAGE" => "Could not update mirror status for mirror '" . $pa_parameters["MIRROR"] . "' on '{$table}'; row_id={$id}\n"));
                     $va_report['errors'][] = _t("Could not update mirror status for mirror '%1' on '%2'; row_id=%3", $pa_parameters["MIRROR"], $table, $id);
                 }
             }
         }
     }
     return $va_report;
 }
예제 #13
0
 /**
  * 
  * Implements standard username/password and IP-address based user authentication. Applications
  * requiring completely custom authentication methods should override this method. However, most of
  * the time if you need custom authentication you can just create a custom user auth handler class ("username/password" authentication).
  * Your custom handler class must implement all of the methods
  * in the user, must be accessible via the php_include_path, and must be added to your Auth instance
  * using addUserHandler().
  *
  * One clean way to extend Auth is create a sub-class whose constructor calls addUserHandler() and delegates
  * everything else to Auth.
  *
  * @access private 
  * @param array of login options (same as the associative option array in the class constructor)
  */
 public function doAuthentication($pa_options)
 {
     global $AUTH_CURRENT_USER_ID;
     $o_event_log = new Eventlog();
     $vs_app_name = $this->config->get("app_name");
     foreach (array('no_headers', 'dont_redirect_to_login', 'dont_create_new_session', 'dont_redirect_to_welcome', 'user_name', 'password', 'options', 'noPublicUsers', 'dont_redirect', 'no_headers') as $vs_key) {
         if (!isset($pa_options[$vs_key])) {
             $pa_options[$vs_key] = null;
         }
     }
     if (!is_array($pa_options["options"])) {
         $pa_options["options"] = array();
     }
     if ($pa_options["no_headers"]) {
         $pa_options["dont_redirect_to_login"] = true;
         $pa_options["dont_create_new_session"] = true;
         $pa_options["dont_redirect_to_welcome"] = true;
     }
     if ($pa_options["dont_redirect"]) {
         $pa_options["dont_redirect_to_login"] = true;
         $pa_options["dont_redirect_to_welcome"] = true;
     }
     $vb_login_successful = false;
     if (!$pa_options["user_name"]) {
         // no incoming login
         //
         // is a user already logged in?
         //
         if ($vn_user_id = $this->session->getVar($vs_app_name . "_user_id")) {
             // does session have a user attached to it?
             // user is already logged in
             $vs_user_class_name = preg_replace("/[^A-Za-z0-9\\-\\_]+/", "", $this->session->getVar($vs_app_name . "_user_classname"));
             if (in_array($vs_user_class_name, $this->userHandlers)) {
                 // make sure auth class is valid
                 if (caFileIsIncludable($vs_user_class_name . ".php")) {
                     require_once $vs_user_class_name . ".php";
                     $va_options = $pa_options["options"];
                     $this->user = new $vs_user_class_name($vn_user_id, $va_options);
                     // add user object
                     if (!$this->user->isActive() || $this->user->numErrors() || $pa_options['noPublicUsers'] && $this->user->isPublicUser()) {
                         // error means user_id in session is invalid
                         $vb_login_successful = false;
                     } else {
                         $vb_login_successful = true;
                     }
                 }
             }
             if ($vb_login_successful) {
                 // Login was successful
                 $this->session->setVar($vs_app_name . "_lastping", time());
                 // set last time we heard from client in session
                 $this->user->setLastPing(time());
                 $AUTH_CURRENT_USER_ID = $vn_user_id;
                 //$this->user->close(); ** will be called externally **
                 return $vb_login_successful;
             }
         }
         if (!$vb_login_successful) {
             foreach ($this->userHandlers as $vs_user_class_name) {
                 $vs_user_class_name = preg_replace("/[^A-Za-z0-9\\-\\_]+/", "", $vs_user_class_name);
                 if (!caFileIsIncludable($vs_user_class_name . ".php")) {
                     continue;
                 }
                 require_once $vs_user_class_name . ".php";
                 $this->user = new $vs_user_class_name();
                 // add user object
                 $vs_tmp1 = $vs_tmp2 = null;
                 if ($vn_auth_type = $this->user->authenticate($vs_tmp1, $vs_tmp2, $pa_options["options"])) {
                     # error means user_id in session is invalid
                     if ($pa_options['noPublicUsers'] && $this->user->isPublicUser() || !$this->user->isActive()) {
                         $vb_login_successful = false;
                         break;
                     }
                     $vb_login_successful = true;
                     $vn_user_id = $this->user->getUserID();
                     break;
                 }
             }
             if (!$vb_login_successful) {
                 // throw user to login screen
                 if (!$pa_options["dont_redirect_to_login"]) {
                     //header("Location: ".$this->getBasePath().'/'.$this->getScriptName().'/'.$this->config->get("auth_login_path"));
                     $this->opo_response->addHeader("Location", $this->getBaseUrlPath() . '/' . $this->getScriptName() . '/' . $this->config->get("auth_login_path"));
                     //exit;
                 }
                 return false;
             }
         }
     }
     //
     // incoming login
     //
     if ($pa_options["user_name"]) {
         $vb_login_successful = false;
         foreach ($this->userHandlers as $vs_user_class_name) {
             $vs_user_class_name = preg_replace("/[^A-Za-z0-9\\-\\_]+/", "", $vs_user_class_name);
             if (!caFileIsIncludable($vs_user_class_name . ".php")) {
                 continue;
             }
             require_once $vs_user_class_name . ".php";
             $this->user = new $vs_user_class_name();
             if ($vn_auth_type = $this->user->authenticate($pa_options["user_name"], $pa_options["password"], $pa_options["options"])) {
                 # error means user_id in session is invalid
                 if ($pa_options['noPublicUsers'] && $this->user->isPublicUser() || !$this->user->isActive()) {
                     $vb_login_successful = false;
                     break;
                 }
                 $vb_login_successful = true;
                 $vn_user_id = $this->user->getUserID();
                 break;
             }
         }
     }
     if (!$vb_login_successful) {
         $this->user = null;
         // auth failed
         // throw user to login screen
         if ($pa_options["user_name"]) {
             $o_event_log->log(array("CODE" => "LOGF", "SOURCE" => "Auth", "MESSAGE" => "Failed login for '" . $pa_options["user_name"] . "' (" . $_SERVER['REQUEST_URI'] . "); IP=" . $_SERVER["REMOTE_ADDR"] . "; user agent='" . $_SERVER["HTTP_USER_AGENT"] . "'"));
         }
         if (!$pa_options["dont_redirect_to_login"]) {
             $vs_auth_login_url = $this->getBaseUrlPath() . '/' . $this->getScriptName() . '/' . $this->config->get("auth_login_path");
             //header("Location: ".$vs_auth_login_url.(($pa_options["user_name"]) ? "&lf=1" : ""));
             $this->opo_response->addHeader("Location", $vs_auth_login_url);
             //exit;
         }
         return false;
     } else {
         $o_event_log->log(array("CODE" => "LOGN", "SOURCE" => "Auth", "MESSAGE" => "Successful login for '" . $pa_options["user_name"] . "'; IP=" . $_SERVER["REMOTE_ADDR"] . "; user agent=" . $_SERVER["HTTP_USER_AGENT"]));
         $this->session->setVar($vs_app_name . "_user_auth_type", $vn_auth_type);
         // type of auth used: 1=username/password; 2=ip-base auth
         $this->session->setVar($vs_app_name . "_user_id", $vn_user_id);
         // auth succeeded; set user_id in session
         $this->session->setVar($vs_app_name . "_user_classname", $this->user->getClassName());
         // auth succeeded; set user_id in session
         $this->session->setVar($vs_app_name . "_logintime", time());
         // also set login time (unix timestamp) in session
         $this->session->setVar($vs_app_name . "_lastping", time());
         $this->session->setVar("screen_width", isset($_REQUEST["_screen_width"]) ? intval($_REQUEST["_screen_width"]) : 0);
         $this->session->setVar("screen_height", isset($_REQUEST["_screen_height"]) ? intval($_REQUEST["_screen_height"]) : 0);
         $this->session->setVar("has_pdf_plugin", isset($_REQUEST["_has_pdf_plugin"]) ? intval($_REQUEST["_has_pdf_plugin"]) : 0);
         $this->user->setVar('last_login', time(), array('volatile' => true));
         $this->user->setLastLogout($this->user->getLastPing(), array('volatile' => true));
         //$this->user->close(); ** will be called externally **
         $AUTH_CURRENT_USER_ID = $vn_user_id;
         if (!$pa_options["dont_redirect_to_welcome"]) {
             //header("Location: ".$this->getBaseUrlPath().'/'.$this->getScriptName().'/'.$this->config->get("auth_login_welcome_path"));				// redirect to "welcome" page
             $this->opo_response->addHeader("Location", $this->getBaseUrlPath() . '/' . $this->getScriptName() . '/' . $this->config->get("auth_login_welcome_path"));
             //exit;
         }
         return true;
     }
 }
예제 #14
0
 /**
  * @param array $pa_options
  *		progressCallback =
  *		reportCallback = 
  *		sendMail = 
  */
 public static function importMediaFromDirectory($po_request, $pa_options = null)
 {
     global $g_ui_locale_id;
     $t_object = new ca_objects();
     $o_eventlog = new Eventlog();
     $t_set = new ca_sets();
     $va_notices = $va_errors = array();
     $vb_we_set_transaction = false;
     $o_trans = isset($pa_options['transaction']) && $pa_options['transaction'] ? $pa_options['transaction'] : null;
     if (!$o_trans) {
         $vb_we_set_transaction = true;
         $o_trans = new Transaction();
     }
     $o_log = new Batchlog(array('user_id' => $po_request->getUserID(), 'batch_type' => 'MI', 'table_num' => (int) $t_object->tableNum(), 'notes' => '', 'transaction' => $o_trans));
     if (!is_dir($pa_options['importFromDirectory'])) {
         $o_eventlog->log(array("CODE" => 'ERR', "SOURCE" => "mediaImport", "MESSAGE" => "Specified import directory is invalid"));
         return null;
     }
     $vs_batch_media_import_root_directory = $po_request->config->get('batch_media_import_root_directory');
     if (!preg_match("!^{$vs_batch_media_import_root_directory}!", $pa_options['importFromDirectory'])) {
         $o_eventlog->log(array("CODE" => 'ERR', "SOURCE" => "mediaImport", "MESSAGE" => "Specified import directory is invalid"));
         return null;
     }
     if (preg_match("!/\\.\\.!", $vs_directory) || preg_match("!\\.\\./!", $pa_options['importFromDirectory'])) {
         $o_eventlog->log(array("CODE" => 'ERR', "SOURCE" => "mediaImport", "MESSAGE" => "Specified import directory is invalid"));
         return null;
     }
     $vb_include_subdirectories = (bool) $pa_options['includeSubDirectories'];
     $vb_delete_media_on_import = (bool) $pa_options['deleteMediaOnImport'];
     $vs_import_mode = $pa_options['importMode'];
     $vs_match_mode = $pa_options['matchMode'];
     $vn_object_type_id = $pa_options['ca_objects_type_id'];
     $vn_rep_type_id = $pa_options['ca_object_representations_type_id'];
     $vn_object_access = $pa_options['ca_objects_access'];
     $vn_object_representation_access = $pa_options['ca_object_representations_access'];
     $vn_object_status = $pa_options['ca_objects_status'];
     $vn_object_representation_status = $pa_options['ca_object_representations_status'];
     $vs_idno_mode = $pa_options['idnoMode'];
     $vs_idno = $pa_options['idno'];
     $vs_set_mode = $pa_options['setMode'];
     $vs_set_create_name = $pa_options['setCreateName'];
     $vn_set_id = $pa_options['set_id'];
     $vn_locale_id = $pa_options['locale_id'];
     $vs_skip_file_list = $pa_options['skipFileList'];
     $va_relationship_type_id_for = array();
     if (is_array($va_create_relationship_for = $pa_options['create_relationship_for'])) {
         foreach ($va_create_relationship_for as $vs_rel_table) {
             $va_relationship_type_id_for[$vs_rel_table] = $pa_options['relationship_type_id_for_' . $vs_rel_table];
         }
     }
     if (!$vn_locale_id) {
         $vn_locale_id = $g_ui_locale_id;
     }
     $va_files_to_process = caGetDirectoryContentsAsList($pa_options['importFromDirectory'], $vb_include_subdirectories);
     if ($vs_set_mode == 'add') {
         $t_set->load($vn_set_id);
     } else {
         if ($vs_set_mode == 'create' && $vs_set_create_name) {
             $va_set_ids = $t_set->getSets(array('user_id' => $po_request->getUserID(), 'table' => 'ca_objects', 'access' => __CA_SET_EDIT_ACCESS__, 'setIDsOnly' => true, 'name' => $vs_set_create_name));
             $vn_set_id = null;
             if (is_array($va_set_ids) && sizeof($va_set_ids) > 0) {
                 $vn_possible_set_id = array_shift($va_set_ids);
                 if ($t_set->load($vn_possible_set_id)) {
                     $vn_set_id = $t_set->getPrimaryKey();
                 }
             } else {
                 $vs_set_code = mb_substr(preg_replace("![^A-Za-z0-9_\\-]+!", "_", $vs_set_create_name), 0, 100);
                 if ($t_set->load(array('set_code' => $vs_set_code))) {
                     $vn_set_id = $t_set->getPrimaryKey();
                 }
             }
             if (!$t_set->getPrimaryKey()) {
                 $t_set->setMode(ACCESS_WRITE);
                 $t_set->set('user_id', $po_request->getUserID());
                 $t_set->set('type_id', $po_request->config->get('ca_sets_default_type'));
                 $t_set->set('table_num', $t_object->tableNum());
                 $t_set->set('set_code', $vs_set_code);
                 $t_set->insert();
                 if ($t_set->numErrors()) {
                     $va_notices['create_set'] = array('idno' => '', 'label' => _t('Create set %1', $vs_set_create_name), 'message' => _t('Failed to create set %1: %2', $vs_set_create_name, join("; ", $t_set->getErrors())), 'status' => 'SET ERROR');
                 } else {
                     $t_set->addLabel(array('name' => $vs_set_create_name), $vn_locale_id, null, true);
                     if ($t_set->numErrors()) {
                         $va_notices['add_set_label'] = array('idno' => '', 'label' => _t('Add label to set %1', $vs_set_create_name), 'message' => _t('Failed to add label to set: %1', join("; ", $t_set->getErrors())), 'status' => 'SET ERROR');
                     }
                     $vn_set_id = $t_set->getPrimaryKey();
                 }
             }
         } else {
             $vn_set_id = null;
             // no set
         }
     }
     if ($t_set->getPrimaryKey() && !$t_set->haveAccessToSet($po_request->getUserID(), __CA_SET_EDIT_ACCESS__)) {
         $va_notices['set_access'] = array('idno' => '', 'label' => _t('You do not have access to set %1', $vs_set_create_name), 'message' => _t('Cannot add to set %1 because you do not have edit access', $vs_set_create_name), 'status' => 'SET ERROR');
         $vn_set_id = null;
         $t_set = new ca_sets();
     }
     $vn_num_items = sizeof($va_files_to_process);
     // Get list of regex packages that user can use to extract object idno's from filenames
     $va_regex_list = $po_request->config->getAssoc('mediaFilenameToObjectIdnoRegexes');
     if (!is_array($va_regex_list)) {
         $va_regex_list = array();
     }
     // Get list of files (or file name patterns) to skip
     $va_skip_list = preg_split("![\r\n]+!", $vs_skip_file_list);
     foreach ($va_skip_list as $vn_i => $vs_skip) {
         if (!strlen($va_skip_list[$vn_i] = trim($vs_skip))) {
             unset($va_skip_list[$vn_i]);
         }
     }
     $vn_c = 0;
     $vn_start_time = time();
     $va_report = array();
     foreach ($va_files_to_process as $vs_file) {
         $va_tmp = explode("/", $vs_file);
         $f = array_pop($va_tmp);
         $d = array_pop($va_tmp);
         array_push($va_tmp, $d);
         $vs_directory = join("/", $va_tmp);
         // Skip file names using $vs_skip_file_list
         if (BatchProcessor::_skipFile($f, $va_skip_list)) {
             continue;
         }
         $vs_relative_directory = preg_replace("!{$vs_batch_media_import_root_directory}[/]*!", "", $vs_directory);
         // does representation already exist?
         if (ca_object_representations::mediaExists($vs_file)) {
             $va_notices[$vs_relative_directory . '/' . $f] = array('idno' => '', 'label' => $f, 'message' => _t('Skipped %1 from %2 because it already exists', $f, $vs_relative_directory), 'status' => 'SKIPPED');
             continue;
         }
         $t_object = new ca_objects();
         $t_object->setTransaction($o_trans);
         $vs_modified_filename = $f;
         $va_extracted_idnos_from_filename = array();
         if (in_array($vs_import_mode, array('TRY_TO_MATCH', 'ALWAYS_MATCH')) || is_array($va_create_relationship_for) && sizeof($va_create_relationship_for)) {
             foreach ($va_regex_list as $vs_regex_name => $va_regex_info) {
                 foreach ($va_regex_info['regexes'] as $vs_regex) {
                     $va_names_to_match = array();
                     switch ($vs_match_mode) {
                         case 'DIRECTORY_NAME':
                             $va_names_to_match = array($d);
                             break;
                         case 'FILE_AND_DIRECTORY_NAMES':
                             $va_names_to_match = array($f, $d);
                             break;
                         default:
                         case 'FILE_NAME':
                             $va_names_to_match = array($f);
                             break;
                     }
                     foreach ($va_names_to_match as $vs_match_name) {
                         if (preg_match('!' . $vs_regex . '!', $vs_match_name, $va_matches)) {
                             if (!$vs_idno || strlen($va_matches[1]) < strlen($vs_idno)) {
                                 $vs_idno = $va_matches[1];
                             }
                             if (!$vs_modified_filename || strlen($vs_modified_filename) > strlen($va_matches[1])) {
                                 $vs_modified_filename = $va_matches[1];
                             }
                             $va_extracted_idnos_from_filename[] = $va_matches[1];
                             if (in_array($vs_import_mode, array('TRY_TO_MATCH', 'ALWAYS_MATCH'))) {
                                 if ($t_object->load(array('idno' => $va_matches[1], 'deleted' => 0))) {
                                     $va_notices[$vs_relative_directory . '/' . $vs_match_name . '_match'] = array('idno' => $t_object->get($t_object->getProperty('ID_NUMBERING_ID_FIELD')), 'label' => $t_object->getLabelForDisplay(), 'message' => _t('Matched media %1 from %2 to object using %2', $f, $vs_relative_directory, $vs_regex_name), 'status' => 'MATCHED');
                                     break 3;
                                 }
                             }
                         }
                     }
                 }
             }
         }
         if (!$t_object->getPrimaryKey()) {
             // Use filename as idno if all else fails
             if ($t_object->load(array('idno' => $f, 'deleted' => 0))) {
                 $va_notices[$vs_relative_directory . '/' . $f . '_match'] = array('idno' => $t_object->get($t_object->getProperty('ID_NUMBERING_ID_FIELD')), 'label' => $t_object->getLabelForDisplay(), 'message' => _t('Matched media %1 from %2 to object using filename', $f, $vs_relative_directory), 'status' => 'MATCHED');
             }
         }
         $t_new_rep = null;
         if ($t_object->getPrimaryKey()) {
             // found existing object
             $t_object->setMode(ACCESS_WRITE);
             $t_new_rep = $t_object->addRepresentation($vs_directory . '/' . $f, $vn_rep_type_id, $vn_locale_id, $vn_object_representation_status, $vn_object_representation_access, false, array(), array('original_filename' => $f, 'returnRepresentation' => true));
             if ($t_object->numErrors()) {
                 $o_eventlog->log(array("CODE" => 'ERR', "SOURCE" => "mediaImport", "MESSAGE" => "Error importing {$f} from {$vs_directory}: " . join('; ', $t_object->getErrors())));
                 $va_errors[$vs_relative_directory . '/' . $f] = array('idno' => $t_object->get($t_object->getProperty('ID_NUMBERING_ID_FIELD')), 'label' => $t_object->getLabelForDisplay(), 'errors' => $t_object->errors(), 'message' => _t("Error importing %1 from %2: %3", $f, $vs_relative_directory, join('; ', $t_object->getErrors())), 'status' => 'ERROR');
                 $o_trans->rollback();
                 continue;
             } else {
                 if ($vb_delete_media_on_import) {
                     @unlink($vs_directory . '/' . $f);
                 }
             }
         } else {
             // should we create new object?
             if (in_array($vs_import_mode, array('TRY_TO_MATCH', 'DONT_MATCH'))) {
                 $t_object->setMode(ACCESS_WRITE);
                 $t_object->set('type_id', $vn_object_type_id);
                 $t_object->set('locale_id', $vn_locale_id);
                 $t_object->set('status', $vn_object_status);
                 $t_object->set('access', $vn_object_access);
                 switch ($vs_idno_mode) {
                     case 'filename':
                         // use the filename as identifier
                         $t_object->set('idno', $f);
                         break;
                     case 'directory_and_filename':
                         // use the directory + filename as identifier
                         $t_object->set('idno', $d . '/' . $f);
                         break;
                     default:
                         // Calculate identifier using numbering plugin
                         $o_numbering_plugin = $t_object->getIDNoPlugInInstance();
                         if (!($vs_sep = $o_numbering_plugin->getSeparator())) {
                             $vs_sep = '';
                         }
                         if (!is_array($va_idno_values = $o_numbering_plugin->htmlFormValuesAsArray('idno', $vs_object_idno, false, false, true))) {
                             $va_idno_values = array();
                         }
                         $t_object->set('idno', join($vs_sep, $va_idno_values));
                         // true=always set serial values, even if they already have a value; this let's us use the original pattern while replacing the serial value every time through
                         break;
                 }
                 $t_object->insert();
                 if ($t_object->numErrors()) {
                     $o_eventlog->log(array("CODE" => 'ERR', "SOURCE" => "mediaImport", "MESSAGE" => "Error creating new object while importing {$f} from {$vs_relative_directory}: " . join('; ', $t_object->getErrors())));
                     $va_errors[$vs_relative_directory . '/' . $f] = array('idno' => $t_object->get($t_object->getProperty('ID_NUMBERING_ID_FIELD')), 'label' => $t_object->getLabelForDisplay(), 'errors' => $t_object->errors(), 'message' => _t("Error creating new object while importing %1 from %2: %3", $f, $vs_relative_directory, join('; ', $t_object->getErrors())), 'status' => 'ERROR');
                     $o_trans->rollback();
                     continue;
                 }
                 $t_object->addLabel(array('name' => $f), $vn_locale_id, null, true);
                 if ($t_object->numErrors()) {
                     $o_eventlog->log(array("CODE" => 'ERR', "SOURCE" => "mediaImport", "MESSAGE" => "Error creating object label while importing {$f} from {$vs_relative_directory}: " . join('; ', $t_object->getErrors())));
                     $va_errors[$vs_relative_directory . '/' . $f] = array('idno' => $t_object->get($t_object->getProperty('ID_NUMBERING_ID_FIELD')), 'label' => $t_object->getLabelForDisplay(), 'errors' => $t_object->errors(), 'message' => _t("Error creating object label while importing %1 from %2: %3", $f, $vs_relative_directory, join('; ', $t_object->getErrors())), 'status' => 'ERROR');
                     $o_trans->rollback();
                     continue;
                 }
                 $t_new_rep = $t_object->addRepresentation($vs_directory . '/' . $f, $vn_rep_type_id, $vn_locale_id, $vn_object_representation_status, $vn_object_representation_access, true, array(), array('original_filename' => $f, 'returnRepresentation' => true));
                 if ($t_object->numErrors()) {
                     $o_eventlog->log(array("CODE" => 'ERR', "SOURCE" => "mediaImport", "MESSAGE" => "Error importing {$f} from {$vs_relative_directory}: " . join('; ', $t_object->getErrors())));
                     $va_errors[$vs_relative_directory . '/' . $f] = array('idno' => $t_object->get($t_object->getProperty('ID_NUMBERING_ID_FIELD')), 'label' => $t_object->getLabelForDisplay(), 'errors' => $t_object->errors(), 'message' => _t("Error importing %1 from %2: %3", $f, $vs_relative_directory, join('; ', $t_object->getErrors())), 'status' => 'ERROR');
                     $o_trans->rollback();
                     continue;
                 } else {
                     if ($vb_delete_media_on_import) {
                         @unlink($vs_directory . '/' . $f);
                     }
                 }
             }
         }
         if ($t_object->getPrimaryKey()) {
             $va_notices[$t_object->getPrimaryKey()] = array('idno' => $t_object->get($t_object->getProperty('ID_NUMBERING_ID_FIELD')), 'label' => $t_object->getLabelForDisplay(), 'message' => _t('Imported %1 as %2', $f, $t_object->get($t_object->getProperty('ID_NUMBERING_ID_FIELD'))), 'status' => 'SUCCESS');
             if ($vn_set_id) {
                 $t_set->addItem($t_object->getPrimaryKey(), null, $po_request->getUserID());
             }
             $o_log->addItem($t_object->getPrimaryKey(), $t_object->getErrors());
             // Create relationships?
             if (is_array($va_create_relationship_for) && sizeof($va_create_relationship_for) && is_array($va_extracted_idnos_from_filename) && sizeof($va_extracted_idnos_from_filename)) {
                 foreach ($va_extracted_idnos_from_filename as $vs_idno) {
                     foreach ($va_create_relationship_for as $vs_rel_table) {
                         if (!isset($va_relationship_type_id_for[$vs_rel_table]) || !$va_relationship_type_id_for[$vs_rel_table]) {
                             continue;
                         }
                         $t_rel = $t_object->getAppDatamodel()->getInstanceByTableName($vs_rel_table);
                         if ($t_rel->load(array($t_rel->getProperty('ID_NUMBERING_ID_FIELD') => $vs_idno))) {
                             $t_object->addRelationship($vs_rel_table, $t_rel->getPrimaryKey(), $va_relationship_type_id_for[$vs_rel_table]);
                             if (!$t_object->numErrors()) {
                                 $va_notices[$t_object->getPrimaryKey() . '_rel'] = array('idno' => $t_object->get($t_object->getProperty('ID_NUMBERING_ID_FIELD')), 'label' => $vs_label = $t_object->getLabelForDisplay(), 'message' => _t('Added relationship between <em>%1</em> and %2 <em>%3</em>', $vs_label, $t_rel->getProperty('NAME_SINGULAR'), $t_rel->getLabelForDisplay()), 'status' => 'RELATED');
                             } else {
                                 $va_notices[$t_object->getPrimaryKey()] = array('idno' => $t_object->get($t_object->getProperty('ID_NUMBERING_ID_FIELD')), 'label' => $vs_label = $t_object->getLabelForDisplay(), 'message' => _t('Could not add relationship between <em>%1</em> and %2 <em>%3</em>: %4', $vs_label, $t_rel->getProperty('NAME_SINGULAR'), $t_rel->getLabelForDisplay(), join("; ", $t_object->getErrors())), 'status' => 'ERROR');
                             }
                         }
                     }
                 }
             }
         } else {
             $va_notices[$vs_relative_directory . '/' . $f] = array('idno' => '', 'label' => $f, 'message' => $vs_import_mode == 'ALWAYS_MATCH' ? _t('Skipped %1 from %2 because it could not be matched', $f, $vs_relative_directory) : _t('Skipped %1 from %2', $f, $vs_relative_directory), 'status' => 'SKIPPED');
         }
         if (isset($pa_options['progressCallback']) && ($ps_callback = $pa_options['progressCallback'])) {
             $ps_callback($po_request, $vn_c, $vn_num_items, _t("[%3/%4] Processing %1 (%3)", caTruncateStringWithEllipsis($vs_relative_directory, 20) . '/' . caTruncateStringWithEllipsis($f, 30), $t_object->get($t_object->getProperty('ID_NUMBERING_ID_FIELD')), $vn_c, $vn_num_items), $t_new_rep, time() - $vn_start_time, memory_get_usage(true), sizeof($va_notices), sizeof($va_errors));
         }
         $vn_c++;
     }
     if (isset($pa_options['progressCallback']) && ($ps_callback = $pa_options['progressCallback'])) {
         $ps_callback($po_request, $vn_num_items, $vn_num_items, _t("Processing completed"), null, time() - $vn_start_time, memory_get_usage(true), sizeof($va_notices), sizeof($va_errors));
     }
     $vn_elapsed_time = time() - $vn_start_time;
     if (isset($pa_options['reportCallback']) && ($ps_callback = $pa_options['reportCallback'])) {
         $va_general = array('elapsedTime' => $vn_elapsed_time, 'numErrors' => sizeof($va_errors), 'numProcessed' => sizeof($va_notices), 'batchSize' => $vn_num_items, 'table' => 'ca_objects', 'set_id' => $t_set->getPrimaryKey(), 'setName' => $t_set->getLabelForDisplay());
         $ps_callback($po_request, $va_general, $va_notices, $va_errors);
     }
     $o_log->close();
     if ($vb_we_set_transaction) {
         if (sizeof($va_errors) > 0) {
             $o_trans->rollback();
         } else {
             $o_trans->commit();
         }
     }
     $vs_set_name = $t_set->getLabelForDisplay();
     $vs_started_on = caGetLocalizedDate($vn_start_time);
     if (isset($pa_options['sendMail']) && $pa_options['sendMail']) {
         if ($vs_email = trim($po_request->user->get('email'))) {
             caSendMessageUsingView($po_request, array($vs_email => $po_request->user->get('fname') . ' ' . $po_request->user->get('lname')), __CA_ADMIN_EMAIL__, _t('[%1] Batch media import completed', $po_request->config->get('app_display_name')), 'batch_media_import_completed.tpl', array('notices' => $va_notices, 'errors' => $va_errors, 'directory' => $vs_relative_directory, 'numErrors' => sizeof($va_errors), 'numProcessed' => sizeof($va_notices), 'subjectNameSingular' => _t('file'), 'subjectNamePlural' => _t('files'), 'startedOn' => $vs_started_on, 'completedOn' => caGetLocalizedDate(time()), 'setName' => $vn_set_id ? $vs_set_name : null, 'elapsedTime' => caFormatInterval($vn_elapsed_time)));
         }
     }
     if (isset($pa_options['sendSMS']) && $pa_options['sendSMS']) {
         SMS::send($po_request->getUserID(), _t("[%1] Media import processing for directory %2 with %3 %4 begun at %5 is complete", $po_request->config->get('app_display_name'), $vs_relative_directory, $vn_num_items, $vn_num_items == 1 ? _t('file') : _t('files'), $vs_started_on));
     }
     return array('errors' => $va_errors, 'notices' => $va_notices, 'processing_time' => caFormatInterval($vn_elapsed_time));
 }
 /**
  * Perform client services-related periodic tasks
  */
 public function hookPeriodicTask(&$pa_params)
 {
     $t_log = new Eventlog();
     $o_db = new Db();
     if (!(bool) $this->opo_config->get('enable_client_services')) {
         return true;
     }
     // Find any orders with status PROCESSED_AWAITING_MEDIA_ACCESS and fetch media
     $qr_orders = $o_db->query("\n\t\t\t\tSELECT order_id\n\t\t\t\tFROM ca_commerce_orders\n\t\t\t\tWHERE\n\t\t\t\t\torder_status = 'PROCESSED_AWAITING_MEDIA_ACCESS'\n\t\t\t");
     //
     // Set up HTTP client for REST calls
     //
     if ($this->opo_client_services_config->get('remote_media_base_url')) {
         $vs_base_url = $this->opo_client_services_config->get('remote_media_base_url');
         $o_client = new RestClient($vs_base_url . "/service.php/iteminfo/ItemInfo/rest");
         try {
             $o_res = $o_client->auth($this->opo_client_services_config->get('remote_media_username'), $this->opo_client_services_config->get('remote_media_password'))->get();
             if (!$o_res->isSuccess()) {
                 $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Could not authenticate to remote system %1', $vs_base_url), 'SOURCE' => 'clientServicesPlugin->hookPeriodicTask'));
             }
             while ($qr_orders->nextRow()) {
                 $t_order = new ca_commerce_orders($qr_orders->get('order_id'));
                 $vb_download_errors = false;
                 if ($t_order->getPrimaryKey() && sizeof($va_missing_media = $t_order->itemsMissingDownloadableMedia())) {
                     $va_missing_media_representation_ids = $t_order->itemsMissingDownloadableMedia('original', array('returnRepresentationIDs' => true));
                     foreach ($va_missing_media as $vn_object_id => $va_representation_md5s) {
                         foreach ($va_representation_md5s as $vn_i => $vs_representation_md5) {
                             $o_xml = $o_client->getObjectRepresentationURLByMD5($vs_representation_md5, 'original')->get();
                             $vs_url = (string) $o_xml->getObjectRepresentationURLByMD5->original;
                             if (!$vs_url) {
                                 continue;
                             }
                             // media no longer exists
                             // fetch the file
                             $t_rep = new ca_object_representations($va_missing_media_representation_ids[$vn_object_id][$vn_i]);
                             if ($t_rep->getPrimaryKey() && ($vs_target_path = $t_rep->getMediaPath('media', 'original'))) {
                                 if ($r_source = fopen($vs_url, "rb")) {
                                     if ($r_target = fopen($vs_target_path, "wb")) {
                                         while (feof($r_source) === false) {
                                             fwrite($r_target, fread($r_source, 1024 * 8), 1024 * 8);
                                         }
                                         fclose($r_target);
                                     } else {
                                         $vb_download_errors = true;
                                         $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Could not open target path %1', $vs_target_path), 'SOURCE' => 'clientServicesPlugin->hookPeriodicTask'));
                                     }
                                     fclose($r_source);
                                 } else {
                                     $vb_download_errors = true;
                                     $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Could not open download URL "%1"', $vs_url), 'SOURCE' => 'clientServicesPlugin->hookPeriodicTask'));
                                 }
                                 // verify the file was downloaded correctly
                                 if (($vs_target_md5 = md5_file($vs_target_path)) !== $vs_representation_md5) {
                                     unlink($vs_target_path);
                                     $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Media file %1 failed to be downloaded from url "%2"; checksums differ: %3/%4', $vs_target_path, $vs_url, $vs_representation_md5, $vs_target_md5), 'SOURCE' => 'clientServicesPlugin->hookPeriodicTask'));
                                     $vb_download_errors = true;
                                 }
                             } else {
                                 $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Invalid representation_id "%1" or target path "%2"', $vn_representation_id, $vs_representation_md5, $vs_target_path), 'SOURCE' => 'clientServicesPlugin->hookPeriodicTask'));
                                 $vb_download_errors = true;
                             }
                         }
                     }
                 }
                 if (!$vb_download_errors) {
                     $t_order->setMode(ACCESS_WRITE);
                     $t_order->set('order_status', 'PROCESSED');
                     $t_order->update();
                     if ($t_order->numErrors()) {
                         $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Change of order status to PROCESSED from PROCESSED_AWAITING_MEDIA_ACCESS failed for order_id %1: %2', $t_order->getPrimaryKey(), join('; ', $t_order->getErrors())), 'SOURCE' => 'clientServicesPlugin->hookPeriodicTask'));
                     }
                 }
             }
         } catch (Exception $e) {
             // noop
         }
     }
     // Find any orders with status PROCESSED_AWAITING_DIGITIZATION where all media are now present
     $qr_orders = $o_db->query("\n\t\t\t\tSELECT order_id\n\t\t\t\tFROM ca_commerce_orders\n\t\t\t\tWHERE\n\t\t\t\t\torder_status = 'PROCESSED_AWAITING_DIGITIZATION'\n\t\t\t");
     while ($qr_orders->nextRow()) {
         $t_order = new ca_commerce_orders($qr_orders->get('order_id'));
         if ($t_order->getPrimaryKey() && !sizeof($t_order->itemsWithNoDownloadableMedia())) {
             $t_order->setMode(ACCESS_WRITE);
             $t_order->set('order_status', 'PROCESSED');
             $t_order->update();
             if ($t_order->numErrors()) {
                 $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Change of order status to PROCESSED from PROCESSED_AWAITING_DIGITIZATION failed for order_id %1: %2', $t_order->getPrimaryKey(), join('; ', $t_order->getErrors())), 'SOURCE' => 'clientServicesPlugin->hookPeriodicTask'));
             }
         }
     }
     // Find orders paid/shipped more than X days ago and mark them as "COMPLETED"
     $vn_days = (int) $this->opo_client_services_config->get('completed_order_age_threshold');
     if ($vn_days > 1) {
         $vn_threshold = (int) (time() - $vn_days * 24 * 60 * 60);
         $qr_orders = $o_db->query("\n\t\t\t\t\tSELECT order_id\n\t\t\t\t\tFROM ca_commerce_orders\n\t\t\t\t\tWHERE\n\t\t\t\t\t\t(order_status = 'PROCESSED') \n\t\t\t\t\t\tAND \n\t\t\t\t\t\t((payment_received_on > 0) AND (payment_received_on < ?))\n\t\t\t\t\t\tAND \n\t\t\t\t\t\t(\n\t\t\t\t\t\t\t(shipping_date IS NULL AND shipped_on_date IS NULL)\n\t\t\t\t\t\t\tOR\n\t\t\t\t\t\t\t(\n\t\t\t\t\t\t\t\t(shipped_on_date > 0) AND (shipped_on_date < ?)\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t)\n\t\t\t\t", $vn_threshold, $vn_threshold);
         while ($qr_orders->nextRow()) {
             $t_order = new ca_commerce_orders($qr_orders->get('order_id'));
             if ($t_order->getPrimaryKey()) {
                 $t_order->setMode(ACCESS_WRITE);
                 $t_order->set('order_status', 'COMPLETED');
                 $t_order->update();
                 if ($t_order->numErrors()) {
                     $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Change of order status to COMPLETED from PROCESSED failed for order_id %1: %2', $t_order->getPrimaryKey(), join('; ', $t_order->getErrors())), 'SOURCE' => 'clientServicesPlugin->hookPeriodicTask'));
                 }
             }
         }
     }
     return true;
 }
예제 #16
0
 public static function check_accounts()
 {
     $accounts = array();
     foreach (Users::get() as $user) {
         if (!$user->info->pbem_active) {
             continue;
         }
         $accounts[$user->name] = array('server' => $user->info->pbem_server, 'protocol' => $user->info->pbem_protocol, 'security' => $user->info->pbem_security, 'mailbox' => $user->info->pbem_mailbox, 'username' => $user->info->pbem_username, 'password' => $user->info->pbem_password, 'whitelist' => $user->info->pbem_whitelist, 'class' => $user->info->pbem_class, 'status' => $user->info->pbem_status, 'user' => $user);
     }
     foreach ($accounts as $user => $account) {
         extract($account);
         // build the $server_string used by imap_open()
         $server_string = '{' . $server;
         switch ("{$protocol}+{$security}") {
             case 'imap+none':
                 $server_string .= ':143/imap}';
                 break;
             case 'imap+ssl':
                 $server_string .= ':993/imap/ssl}';
                 break;
             case 'imap+tls':
                 $server_string .= ':143/imap/tls}';
                 break;
             case 'pop3+none':
                 $server_string .= ':110/pop3}';
                 break;
             case 'pop3+ssl':
                 $server_string .= ':995/pop3/ssl}';
                 break;
             case 'pop3+tls':
                 $server_string .= ':110/pop3/tls}';
         }
         $server_string .= $mailbox;
         $mh = imap_open($server_string, $username, $password, OP_SILENT | OP_DEBUG) or Eventlog::log(_t('Unable to connect'));
         // get a better error, one with imap_*
         $n = imap_num_msg($mh);
         $whitelist = explode("\n", $whitelist);
         $messages_skipped = 0;
         for ($i = 1; $i <= $n; $i++) {
             $body = '';
             $attachments = array();
             $media = array();
             $header = imap_header($mh, $i);
             $whitelist_passed = false;
             foreach ($whitelist as $item) {
                 $item = trim(strtolower($item));
                 if ('' == $item) {
                     continue;
                 }
                 // blanks in whitelist
                 if (false != strpos(strtolower($header->fromaddress), $item)) {
                     $whitelist_passed = true;
                     break;
                 }
             }
             if ($whitelist_passed == false) {
                 ++$messages_skipped;
                 // Move onto the next message.
                 continue;
             }
             // get the message structure
             $structure = imap_fetchstructure($mh, $i);
             if (!isset($structure->parts)) {
                 // message is not not multipart
                 $body = imap_body($mh, $i);
                 // fetchbody only works for single part messages.
                 if ($structure->encoding == 4) {
                     $body = quoted_printable_decode($body);
                     // there's room here for more stuff, with strtoupper($structure->subtype...)
                 }
             } else {
                 if (isset($structure->parts) && count($structure->parts)) {
                     for ($j = 0; $j < count($structure->parts); $j++) {
                         $attachments[$j] = array('is_attachment' => false, 'filename' => '', 'subtype' => '', 'name' => '', 'attachment' => '');
                         if ($structure->parts[$j]->ifdparameters) {
                             foreach ($structure->parts[$j]->dparameters as $object) {
                                 if (strtolower($object->attribute) == 'filename') {
                                     $attachments[$j]['is_attachment'] = true;
                                     $attachments[$j]['filename'] = $object->value;
                                     $attachments[$j]['subtype'] = $structure->parts[$j]->subtype;
                                 }
                             }
                         } elseif (strtolower($structure->parts[$j]->subtype) == 'plain') {
                             $body .= imap_fetchbody($mh, $i, $j + 1);
                         }
                         if ($structure->parts[$j]->ifparameters) {
                             foreach ($structure->parts[$j]->parameters as $object) {
                                 if (strtolower($object->attribute) == 'name') {
                                     $attachments[$j]['is_attachment'] = true;
                                     $attachments[$j]['name'] = $object->value;
                                     if (!isset($attachments[$j]['subtype'])) {
                                         // may not be necessary
                                         $attachments[$j]['subtype'] = $structure->parts[$j]->subtype;
                                         // may not be necessary
                                     }
                                     // may not be necessary
                                 }
                             }
                         }
                         if ($attachments[$j]['is_attachment']) {
                             $attachments[$j]['attachment'] = imap_fetchbody($mh, $i, $j + 1);
                             if ($structure->parts[$j]->encoding == 3) {
                                 // 3 = BASE64
                                 $attachments[$j]['attachment'] = base64_decode($attachments[$j]['attachment']);
                                 $path = self::store($attachments[$j]['filename'], $attachments[$j]['attachment']);
                                 if (false !== $path) {
                                     $media[$attachments[$j]['filename']] = $path;
                                 }
                             } elseif ($structure->parts[$j]->encoding == 4) {
                                 // 4 = QUOTED-PRINTABLE
                                 $attachments[$j]['attachment'] = quoted_printable_decode($attachments[$j]['attachment']);
                                 $body .= $attachments[$j]['attachment'];
                             }
                         }
                     }
                 }
             }
             $tags = $user->info->pbem_tags;
             // if the first line of the message starts with 'tags:', read that line into tags.
             if (stripos($body, 'tags:') === 0) {
                 list($additional_tags, $body) = explode("\n", $body, 2);
                 $tags .= ',' . trim(substr($additional_tags, 5));
                 $body = trim($body);
             }
             if (!empty($media)) {
                 $storage = $user->info->pbem_storage;
                 // filter the post body
                 $body = Plugins::filter("pbem_store_{$storage}", $body, $media, $user, $tags);
             }
             $postdata = array('slug' => $header->subject, 'title' => $header->subject, 'tags' => $tags, 'content' => $body, 'user_id' => $user->id, 'pubdate' => HabariDateTime::date_create(), 'status' => Post::status($status), 'content_type' => Post::type('entry'));
             $headerdate = new DateTime($header->date);
             // now in explicit format
             $headerdate = $headerdate->format(_t('Y-m-d H:i:s'));
             EventLog::log(_t('Mail from %1$s (%2$s): "%3$s" (%4$d bytes)', array(Inputfilter::filter($header->from[0]->mailbox . '@' . $header->from[0]->host), $headerdate, Inputfilter::filter($header->subject), $header->Size)));
             $post = Post::create($postdata);
             if ($post) {
                 // done with the message, now delete it. Comment out if you're testing.
                 imap_delete($mh, $i);
             } else {
                 EventLog::log('Failed to create a new post?');
             }
         }
         imap_expunge($mh);
         imap_close($mh);
         if ($messages_skipped > 0) {
             EventLog::log(_t('Skipped %d messages from senders not on the whitelist.', array($messages_skipped)));
         }
     }
 }