Esempio n. 1
0
 /**
  * Execute a raw SQL query.
  *
  * @param string $sql The SQL to execute.
  * @param array $params Parameters used in the SQL.
  */
 public function query($sql, array $params = array())
 {
     $querytype = mb_strtoupper(mb_substr($sql, 0, 6));
     // Ensure UTF-8.
     foreach ($params as $k => $v) {
         $params[$k] = \pdyn\datatype\Text::force_utf8($v);
     }
     // Prefix tables.
     $sql = preg_replace_callback('#\\{(.+)\\}#msU', function ($matches) {
         return $this->transform_tablename($matches[1]);
     }, $sql);
     // Logging.
     $this->log($sql, $params);
     if (!is_array($params)) {
         throw new \Exception('Bad params argument in $DB->query', static::ERR_DB_BAD_REQUEST);
     }
     if (empty($this->link)) {
         throw new \Exception('No database connection present.', static::ERR_DB_BAD_REQUEST);
     }
     if (empty($params)) {
         $stmt = $this->link->query($sql);
     } else {
         $stmt = $this->link->prepare($sql, [\PDO::ATTR_CURSOR => \PDO::CURSOR_FWDONLY]);
         if (!empty($stmt)) {
             $stmt->execute($params);
             $errinfo = $stmt->errorInfo();
             if ($errinfo[0] !== '00000') {
                 throw new \Exception($errinfo[2], static::ERR_DB_BAD_REQUEST);
             }
             if (in_array($querytype, ['INSERT', 'UPDATE', 'DELETE'], true)) {
                 $affected_rows = $stmt->rowCount();
             }
         }
     }
     $errinfo = $this->link->errorInfo();
     if ($errinfo[0] !== '00000') {
         throw new \Exception($errinfo[2], static::ERR_DB_BAD_REQUEST);
     }
     $this->numqueries++;
     $this->laststmt = $stmt;
     $lastid = $this->link->lastInsertId();
     $ar = ['affected_rows' => isset($affected_rows) ? $affected_rows : -1, 'last_id' => $querytype === 'INSERT' && !empty($lastid) ? $lastid : 0];
     return $ar;
 }
Esempio n. 2
0
 /**
  * Generate a unqiue text-identifier for a given table and column from any input string.
  *
  * Will generate a text identifier from the string (lowercase, alphanum-only), search for the value in the given table/column,
  * and keep incrementing a suffixed counter until the value is unique.
  *
  * @param \pdyn\database\DbDriverInterface $DB An active database connection.
  * @param string $input Any input text.
  * @param string $table The table in which to ensure uniqueness.
  * @param string $field The column in which to ensure uniqueness.
  * @param array $restriction_list Array of values the text-identifier cannot match.
  * @return string The generated, unique text identifier.
  */
 public static function generate_slug(\pdyn\database\DbDriverInterface $DB, $input, $table, $field, array $restriction_list = array())
 {
     $i = 0;
     while (true) {
         $slug = \pdyn\datatype\Text::make_slug($input);
         $slug .= $i != 0 ? '_' . $i : '';
         // This is so we don't add the increment on the first loop.
         if (!empty($restriction_list) && in_array($slug, $restriction_list, true)) {
             $i++;
             continue;
         }
         $found = $DB->get_record($table, [$field => $slug]);
         if (empty($found)) {
             break;
         }
         $i++;
     }
     return $slug;
 }
Esempio n. 3
0
 /**
  * Force a value to UTF-8, then serialize.
  *
  * This is used before storing serialized values in the database. Since our DbDrivers convert all strings to UTF-8,
  * they can damage seralized data. For example, if non-utf8 text is contained in a serialized array, the offset recorded in the
  * serialized string may be not reflect the length after conversion to utf8.
  *
  * @param mixed $input A value to force to UTF-8 then serialize.
  * @return string A serialized UTF-8 value.
  */
 public static function utf8safe_serialize($input)
 {
     if (is_array($input)) {
         return serialize(\pdyn\datatype\Text::force_utf8_array($input));
     } elseif (is_string($input)) {
         return serialize(\pdyn\datatype\Text::force_utf8($input));
     } else {
         return serialize($input);
     }
 }
Esempio n. 4
0
 /**
  * Tests make_slug function.
  *
  * @dataProvider dataprovider_makeSlug
  */
 public function test_makeSlug($text, $expected)
 {
     $actual = \pdyn\datatype\Text::make_slug($text);
     $this->assertEquals($expected, $actual);
 }
Esempio n. 5
0
 /**
  * Transform a value into a storable representation.
  *
  * @param mixed $val A value to transform.
  * @param string $datatype The datatype of the value.
  * @return string|int|float The transformed value.
  */
 public function cast_val($val, $datatype)
 {
     // Translate non-storable values.
     if (is_bool($val)) {
         $val = (int) $val;
     } elseif (is_array($val)) {
         $val = \pdyn\datatype\Text::utf8safe_serialize($val);
     } elseif (!is_scalar($val)) {
         $val = '';
     }
     // Cast for column type (if possible).
     switch ($datatype) {
         case 'timestamp':
         case 'int':
         case 'bigint':
         case 'id':
         case 'bool':
         case 'user_id':
             $val = (int) $val;
             break;
         case 'float':
             $val = (double) $val;
             break;
         default:
             $val = (string) $val;
     }
     return $val;
 }