Exemple #1
0
 /**
  * Generate a pseudo-random password with letters, numbers, and symbols.
  *
  * @param int $length
  * @return string
  * @uses Helpers::is_valid_int()
  */
 public static function generateRandom($length = 64)
 {
     // input validation
     if (!Helpers::is_valid_int($length, true)) {
         return '';
     }
     // generate a pseudo-random password
     $password = '';
     // these are used in the for loop
     $char_types = array('lower_letters' => 'abcdefghijklmnopqrstuvwxyz', 'upper_letters' => 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'numbers' => '0123456789', 'symbols' => '`~!@#$%^*()-_=+[{]}|:,.?');
     $types = array_keys($char_types);
     $max_same = 3;
     $last_type = -1;
     $same_type = 0;
     for ($i = 0; $i < $length; $i++) {
         // determine the type of the character
         $type_index = rand(0, count($types) - 1);
         $type = $char_types[$types[$type_index]];
         if ($last_type === $type_index) {
             $same_type++;
         } else {
             $same_type = 0;
         }
         if ($same_type > 2) {
             $i--;
             continue;
         }
         // determine how many characters to use for type
         $num_same = rand(1, $max_same);
         for ($j = 0; $j < $num_same; $j++) {
             $password .= substr(${$type}, rand(0, strlen(${$type}) - 1), 1);
             if ($j > 0) {
                 $i++;
             }
         }
         $last_type = $type_index;
         if (strlen($password) >= $length) {
             break;
         }
     }
     return substr($password, 0, $length);
 }
Exemple #2
0
 /**
  * Build constants from values in database and store them in a PHP file. Require the file at the end of execution.
  *
  * @return bool
  * @uses Constants::getQuery()
  * @uses Generator::setIterator()
  * @uses Generator::buildTopContent()
  * @uses Constants::generate()
  * @uses Constants::write()
  */
 public function build()
 {
     $this->Log->write(__METHOD__, Log::LOG_LEVEL_SYSTEM_INFORMATION);
     // get constant list
     $this->Log->write('getting constant list', Log::LOG_LEVEL_USER);
     $result = $this->getQuery();
     if (!Helpers::is_array_ne($result)) {
         $this->Log->write('could not get constant list', Log::LOG_LEVEL_WARNING);
         return false;
     }
     list($sql, $params) = $result;
     // set the iterator from the SQL and parameters
     $set_iterator = $this->setIterator($sql, $params);
     if (!$set_iterator) {
         $this->Log->write('could not set iterator with SQL and params', Log::LOG_LEVEL_WARNING, $result);
     }
     $this->Log->write('have constant list', Log::LOG_LEVEL_USER);
     // build the top content of the PHP file
     $size = $this->buildTopContent(__CLASS__);
     if (!Helpers::is_valid_int($size) || $size < 1) {
         $this->Log->write('could not write top content', Log::LOG_LEVEL_WARNING, __CLASS__);
         return false;
     }
     // write after each call to generate to decrease memory consumption on server
     foreach ($this->iterator as $i => $row) {
         $generated = $this->generate($row);
         if ($generated === false) {
             $this->Log->write($i . ': Failed to generate code from row', Log::LOG_LEVEL_WARNING);
             continue;
         }
         $bytes = $this->write();
         if ($bytes === false) {
             $this->Log->write($i . ': could not write PHP to file', Log::LOG_LEVEL_WARNING);
         }
     }
     // require the generated file to provide constants to the rest of the application
     require_once $this->file_path;
     return true;
 }
Exemple #3
0
 /**
  * Update a table based on key/value pairs and WHERE parameters
  *
  * @param string $table Table to update
  * @param array $pairs Key/value pairs to SET
  * @param array $where Where values
  * @param int $limit Limit value (only positive integers will be used for limiting)
  * @param bool $enqueue Enqueue or execute the SQL
  * @return bool|mixed
  * @uses Db::buildUpdate()
  * @uses Db::where()
  * @uses Db::begin()
  * @uses Db::query()
  * @uses Db::commit()
  */
 public function update($table = '', $pairs = array(), $where = array(), $limit = -1, $enqueue = false)
 {
     $this->Log->write(__METHOD__, Log::LOG_LEVEL_SYSTEM_INFORMATION);
     // input validation
     if (!Helpers::is_string_ne($table) || !Helpers::is_array_ne($pairs)) {
         $this->Log->write('table OR pairs is empty', Log::LOG_LEVEL_WARNING);
         return false;
     }
     if (!Helpers::is_array_ne($where)) {
         $this->Log->write('there is no where clause', Log::LOG_LEVEL_WARNING);
         // there might be a problem: we will update everything
         // TODO: determine the best way to handle no WHERE clause
         return false;
     }
     // build SQL
     list($sql, $params) = $this->buildUpdate($table, $pairs);
     // handle WHERE
     list($wsql, $wparams) = $this->where($where);
     $sql .= $wsql;
     $params = array_merge($params, $wparams);
     // handle LIMIT
     if (Helpers::is_valid_int($limit, true)) {
         $sql .= PHP_EOL . '  LIMIT ' . $limit;
     }
     if ($enqueue) {
         $this->Log->write('enqueue sql', Log::LOG_LEVEL_SYSTEM_INFORMATION);
         return $this->enqueue($sql, $params, 'update');
     } else {
         $this->Log->write('updating sql in transaction', Log::LOG_LEVEL_SYSTEM_INFORMATION);
         // execute UPDATE query in transaction
         $this->begin();
         $updated = $this->query($sql, $params, 'update');
         $this->commit();
         $this->Log->write('committed transaction for update', Log::LOG_LEVEL_USER);
         return $updated;
     }
 }
Exemple #4
0
 /**
  * Return error message, based on upload error status.
  *
  * @param int $error
  * @return bool|string
  */
 private function handleError($error)
 {
     $this->Log->write(__METHOD__, Log::LOG_LEVEL_SYSTEM_INFORMATION);
     if (!Helpers::is_valid_int($error, true)) {
         $this->Log->write('Cannot handle an error that is not a positive integer.', Log::LOG_LEVEL_WARNING);
         return false;
     }
     switch ($error) {
         case UPLOAD_ERR_INI_SIZE:
             $message = 'The uploaded file exceeds the upload_max_filesize directive in php.ini.';
             break;
         case UPLOAD_ERR_FORM_SIZE:
             $message = 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.';
             break;
         case UPLOAD_ERR_PARTIAL:
             $message = 'The uploaded file was only partially uploaded.';
             break;
         case UPLOAD_ERR_NO_FILE:
             $message = 'No file was uploaded.';
             break;
         case UPLOAD_ERR_NO_TMP_DIR:
             $message = 'Missing a temporary folder.';
             break;
         case UPLOAD_ERR_CANT_WRITE:
             $message = 'Failed to write file to disk.';
             break;
         case UPLOAD_ERR_EXTENSION:
             $message = 'A PHP extension stopped the file upload.';
             break;
         default:
             $message = 'Unknown upload error (' . Helpers::get_string($error) . ')';
             break;
     }
     $this->Log->write('Error: ' . $message, Log::LOG_LEVEL_ERROR);
     return $message;
 }
Exemple #5
0
 /**
  * Get the user from the database and store in a property.
  *
  * @return array|bool|mixed
  */
 private function getUser()
 {
     $this->Log->write(__METHOD__, Log::LOG_LEVEL_SYSTEM_INFORMATION);
     // use cached version
     if (Helpers::is_array_ne($this->user_data)) {
         return $this->user_data;
     }
     // determine which field and value to use in the query
     if (Helpers::is_valid_int($this->id, true)) {
         $where_field = $this->id_field;
         $value = $this->id;
     } elseif (Helpers::is_string_ne($this->name)) {
         $where_field = $this->name_field;
         $value = $this->name;
     } elseif (array_key_exists('user_id', $_SESSION)) {
         $where_field = $this->id_field;
         $value = $_SESSION['user_id'];
     } elseif (array_key_exists('user_name', $_SESSION)) {
         $where_field = $this->name_field;
         $value = $_SESSION['user_name'];
     } else {
         $this->Log->write('cannot determine user data to use', Log::LOG_LEVEL_WARNING);
         return false;
     }
     // build query
     $sql = 'SELECT *' . PHP_EOL;
     $sql .= '  FROM ' . $this->table . PHP_EOL;
     $sql .= '  WHERE ' . $where_field . ' = ?';
     $row = $this->query($sql, array($value), 'first');
     if (!Helpers::is_array_ne($row)) {
         return false;
     }
     $this->user_data = $row;
     $this->id = $row['id'];
     $this->name = $row['name'];
     return $row;
 }
Exemple #6
0
 /**
  * Set and/or get the log level.
  *
  * [@param] int $log_level Optional log level value
  * @return int
  */
 public function logLevel()
 {
     // set the log level if the parameter is valid
     $args = func_get_args();
     if (count($args) === 1) {
         if (Helpers::is_valid_int($args[0]) && $this->validateLevel($args[0])) {
             $this->log_level = $args[0];
         } else {
             $this->write('invalid log level {' . $args[0] . '}', Log::LOG_LEVEL_WARNING);
         }
     }
     // return the log level
     return $this->log_level;
 }
 /**
  * Removes duplicate rows (based on UNIQUE key), tracks duplicated IDs, and maps duplicate IDs to unique IDs.
  *
  * @param string $table To table name
  * @param array $rows All rows from the table that need to be inserted
  * @return bool
  * @uses Db::getKeyField()
  * @uses $GLOBALS['table_relationships']
  * @uses DatabaseMap::$unique_fields
  * @uses Db::getIdFromName()
  * @see  Relationship::build()
  */
 private function fixDuplicateIds($table = '', &$rows = array())
 {
     $this->Log->write(__METHOD__, Log::LOG_LEVEL_SYSTEM_INFORMATION);
     // input validation
     if (!Helpers::is_string_ne($table)) {
         $this->Log->write('table is invalid', Log::LOG_LEVEL_WARNING, $table);
         return false;
     }
     if (!Helpers::is_array_ne($rows)) {
         $this->Log->write('array is invalid', Log::LOG_LEVEL_WARNING, $rows);
         return false;
     }
     // get this table's unique fields
     $unique_fields = $this->getKeyField($table, 'unique');
     // prepare unique array based on $unique_fields (which might be empty)
     $unique = array();
     foreach ($unique_fields as $field) {
         $unique[$field] = array();
     }
     // get relationships for $table as child table
     if (array_key_exists($table, $GLOBALS['table_relationships'])) {
         $relation = $GLOBALS['table_relationships'][$table];
         $result = $this->buildTableFieldValues($relation);
         if ($result === false) {
             $this->Log->write('Could not get values from relations', Log::LOG_LEVEL_USER, $relation);
         } elseif ($result === 0) {
             $this->Log->write('Found no values from relations', Log::LOG_LEVEL_USER, $relation);
         } else {
             $this->Log->write('Found values', Log::LOG_LEVEL_USER, $result);
         }
     }
     // fix the rows
     foreach ($rows as $index => &$row) {
         // check for duplicate rows
         foreach ($unique_fields as $field) {
             $value = $row[$field];
             $existing_id = $this->getIdFromName($table, $value, $field);
             if (Helpers::is_valid_int($existing_id) && $existing_id > 0) {
                 // consider unique values already in the database table
                 $unique[$field][$value][] = $existing_id;
                 unset($rows[$index]);
                 continue 2;
             } elseif (array_key_exists($value, $unique[$field])) {
                 // remove rows that would duplicate unique values
                 $unique[$field][$value][] = $row['id'];
                 unset($rows[$index]);
                 continue 2;
             } else {
                 // this is the first instance of this value, so build a list for future mapping of IDs
                 $unique[$field][$value] = array();
             }
         }
         // check relationships in order to change parent IDs in rows to use actual parent ID values (after removing duplicates)
         if (isset($relation)) {
             // loop through relations to find parent tables for the child fields
             foreach ($relation as $field => $array) {
                 // make sure the child field exists in the row
                 if (!array_key_exists($field, $row)) {
                     continue;
                 }
                 // make sure this parent table exists in unique fields
                 $relation_table = $relation[$field]['table'];
                 if (!array_key_exists($relation_table, $this->unique_fields)) {
                     continue;
                 }
                 // check for the current row's parent ID in the unique_fields for the parent table
                 $current_id = $row[$field];
                 $use_value = null;
                 $use_field = null;
                 foreach ($this->unique_fields[$relation_table] as $unique_field => $values) {
                     foreach ($values as $value => $ids) {
                         // get the field and value used for this parent ID to use later
                         if (in_array($current_id, $ids)) {
                             $use_value = $value;
                             $use_field = $unique_field;
                             break 2;
                         }
                     }
                 }
                 // make sure there is a value to use to proceed
                 if ($use_value === null) {
                     continue;
                 }
                 // get the actual parent ID for the field and value that were found earlier
                 $use_id = $this->getIdFromName($relation[$field]['table'], $use_value, $use_field);
                 if (!Helpers::is_valid_int($use_id) || $use_id === 0) {
                     $this->Log->write('could not get ID from ' . $relation[$field]['table'] . ' for ' . $use_value, Log::LOG_LEVEL_WARNING);
                     continue;
                 }
                 // update the row to use the actual parent ID for the value (like find and replace)
                 $row[$field] = $use_id;
                 // check for existence of key field value before allowing it to be inserted (in order to avoid foreign
                 // key constraint violations) and generate a report of the rows that would have failed
                 if (!in_array($use_id, $this->table_field_values[$array['table']][$array['field']])) {
                     $this->missing_keys[$array['table']][$array['field']][] = $use_id;
                     $this->missing_keys[$array['table']][$array['field']] = array_unique($this->missing_keys[$array['table']][$array['field']]);
                     sort($this->missing_keys[$array['table']][$array['field']]);
                     //unset($rows[$index]);
                 }
             }
         }
     }
     // sort by either first field, id field, or specified field in parameters
     usort($rows, function ($a, $b) {
         if (array_key_exists('id', $a) && array_key_exists('id', $b)) {
             $id_field = 'id';
             $id_field_a = $id_field;
             $id_field_b = $id_field;
         } else {
             // get first key
             $keys = array_keys($a);
             $id_field_a = $keys[0];
             $keys = array_keys($b);
             $id_field_b = $keys[0];
         }
         return $a[$id_field_a] > $b[$id_field_b];
     });
     // save any values from $unique to the unique fields array to use in the loop above
     $this->unique_fields[$table] = $unique;
     return true;
 }
Exemple #8
0
 /**
  * Set and/or get the log level.
  *
  * @return int
  * @uses Log::validateLevel()
  */
 public function logLevel()
 {
     $args = func_get_args();
     if (Helpers::is_array_ne($args)) {
         if (Helpers::is_valid_int($args[0]) && (is_object($this->Log) && $this->Log->validateLevel($args[0]))) {
             $this->log_level = $args[0];
             $this->Log->logLevel($this->log_level);
         }
     }
     return $this->log_level;
 }
Exemple #9
0
 /**
  * Get the last successful login attempt from the database.
  *
  * @param int $user_id
  * @return bool|mixed
  */
 public function lastSuccessful($user_id = 0)
 {
     $this->Log->write(__METHOD__, Log::LOG_LEVEL_SYSTEM_INFORMATION);
     if (!Helpers::is_valid_int($user_id, true)) {
         $this->Log->write('invalid user id', Log::LOG_LEVEL_WARNING, $user_id);
         return false;
     }
     $sql = 'SELECT *' . PHP_EOL;
     $sql .= '  FROM ' . $this->table . PHP_EOL;
     $sql .= '  WHERE user_id = ?' . PHP_EOL;
     $sql .= '    AND success = 1' . PHP_EOL;
     $sql .= '  ORDER BY add_date DESC' . PHP_EOL;
     $sql .= '  LIMIT 1';
     $row = $this->query($sql, array($user_id), 'single');
     $this->Log->write('found row', Log::LOG_LEVEL_USER, $row);
     return $row;
 }
Exemple #10
0
 /**
  * Convert a text file (with appropriate file extension [docx, doc, odt, txt]) to a PDF file.
  * This uses Libre Office, a command line utility, to convert the file in the file system and requires exec permission.
  *
  * @return bool|mixed
  * @uses Convert::$input_file
  * @uses Convert::replaceExtension()
  */
 private function textToPdf()
 {
     if (!is_file($this->input_file)) {
         $this->Log->write('Input file is not part of this file system. Please specify the correct file with Convert::inputFile() or Convert::uploadFile().', Log::LOG_LEVEL_WARNING);
         return false;
     }
     $command = '/usr/bin/soffice --headless --convert-to pdf ' . $this->input_file;
     exec($command, $output, $return_var);
     if (Helpers::is_valid_int($return_var) && $return_var != 0) {
         $this->Log->write('An error occurred when executing command:' . PHP_EOL . implode(PHP_EOL, $output), Log::LOG_LEVEL_WARNING);
         return false;
     }
     $output_file = $this->replaceExtension('pdf');
     return $output_file;
 }