vendor/pimcore/pimcore/lib/Db/Helper.php line 63

Open in your IDE?
  1. <?php
  2. /**
  3.  * Pimcore
  4.  *
  5.  * This source file is available under two different licenses:
  6.  * - GNU General Public License version 3 (GPLv3)
  7.  * - Pimcore Commercial License (PCL)
  8.  * Full copyright and license information is available in
  9.  * LICENSE.md which is distributed with this source code.
  10.  *
  11.  *  @copyright  Copyright (c) Pimcore GmbH (http://www.pimcore.org)
  12.  *  @license    http://www.pimcore.org/license     GPLv3 and PCL
  13.  */
  14. namespace Pimcore\Db;
  15. use Doctrine\DBAL\Driver\Result;
  16. use Doctrine\DBAL\Types\Type;
  17. use Pimcore\Model\Element\ValidationException;
  18. class Helper
  19. {
  20.     /**
  21.      *
  22.      * @param array<string, mixed> $data The data to be inserted or updated into the database table.
  23.      * Array key corresponds to the database column, array value to the actual value.
  24.      * @param string[] $keys If the table needs to be updated, the columns listed in this parameter will be used as criteria/condition for the where clause.
  25.      * Typically, these are the primary key columns.
  26.      * The values for the specified keys are read from the $data parameter.
  27.      */
  28.     public static function upsert(ConnectionInterface|\Doctrine\DBAL\Connection $connectionstring $table, array $data, array $keysbool $quoteIdentifiers true): int|string
  29.     {
  30.         try {
  31.             $data $quoteIdentifiers self::quoteDataIdentifiers($connection$data) : $data;
  32.             return $connection->insert($table$data);
  33.         } catch (\Doctrine\DBAL\Exception\UniqueConstraintViolationException $exception) {
  34.             $critera = [];
  35.             foreach ($keys as $key) {
  36.                 $key $quoteIdentifiers $connection->quoteIdentifier($key) : $key;
  37.                 $critera[$key] = $data[$key] ?? throw new \LogicException(sprintf('Key "%s" passed for upsert not found in data'$key));
  38.             }
  39.             return $connection->update($table$data$critera);
  40.         }
  41.     }
  42.     /**
  43.      * @deprecated will be removed in Pimcore 11. Use Pimcore\Db\Helper::upsert instead.
  44.      *
  45.      * @param ConnectionInterface|\Doctrine\DBAL\Connection $connection
  46.      * @param string $table
  47.      * @param array $data
  48.      *
  49.      * @return int|string
  50.      */
  51.     public static function insertOrUpdate(ConnectionInterface|\Doctrine\DBAL\Connection $connection$table, array $data)
  52.     {
  53.         trigger_deprecation(
  54.             'pimcore/pimcore',
  55.             '10.6.0',
  56.             sprintf('%s is deprecated and will be removed in Pimcore 11. Use Pimcore\Db\Helper::upsert() instead.'__METHOD__)
  57.         );
  58.         // extract and quote col names from the array keys
  59.         $i 0;
  60.         $bind = [];
  61.         $cols = [];
  62.         $vals = [];
  63.         foreach ($data as $col => $val) {
  64.             $cols[] = $connection->quoteIdentifier($col);
  65.             $bind[':col' $i] = $val;
  66.             $vals[] = ':col' $i;
  67.             $i++;
  68.         }
  69.         // build the statement
  70.         $set = [];
  71.         foreach ($cols as $i => $col) {
  72.             $set[] = sprintf('%s = %s'$col$vals[$i]);
  73.         }
  74.         $sql sprintf(
  75.             'INSERT INTO %s (%s) VALUES (%s) ON DUPLICATE KEY UPDATE %s;',
  76.             $connection->quoteIdentifier($table),
  77.             implode(', '$cols),
  78.             implode(', '$vals),
  79.             implode(', '$set)
  80.         );
  81.         $bind array_merge($bind$bind);
  82.         return $connection->executeStatement($sql$bind);
  83.     }
  84.     /**
  85.      * @param ConnectionInterface|\Doctrine\DBAL\Connection $db
  86.      * @param string $sql
  87.      * @param array $params
  88.      * @param array $types
  89.      *
  90.      * @return array
  91.      */
  92.     public static function fetchPairs(ConnectionInterface|\Doctrine\DBAL\Connection $db$sql, array $params = [], $types = [])
  93.     {
  94.         $stmt $db->executeQuery($sql$params$types);
  95.         $data = [];
  96.         if ($stmt instanceof Result) {
  97.             while ($row $stmt->fetchNumeric()) {
  98.                 $data[$row[0]] = $row[1];
  99.             }
  100.         }
  101.         return $data;
  102.     }
  103.     /**
  104.      * @param ConnectionInterface|\Doctrine\DBAL\Connection $db
  105.      * @param string $table
  106.      * @param string $idColumn
  107.      * @param string $where
  108.      *
  109.      * @return void
  110.      */
  111.     public static function selectAndDeleteWhere(ConnectionInterface|\Doctrine\DBAL\Connection $db$table$idColumn 'id'$where '')
  112.     {
  113.         $sql 'SELECT ' $db->quoteIdentifier($idColumn) . '  FROM ' $table;
  114.         if ($where) {
  115.             $sql .= ' WHERE ' $where;
  116.         }
  117.         $idsForDeletion $db->fetchFirstColumn($sql);
  118.         if (!empty($idsForDeletion)) {
  119.             $chunks array_chunk($idsForDeletion1000);
  120.             foreach ($chunks as $chunk) {
  121.                 $idString implode(','array_map([$db'quote'], $chunk));
  122.                 $db->executeStatement('DELETE FROM ' $table ' WHERE ' $idColumn ' IN (' $idString ')');
  123.             }
  124.         }
  125.     }
  126.     /**
  127.      * @param ConnectionInterface|\Doctrine\DBAL\Connection $db
  128.      * @param string $sql
  129.      * @param array $exclusions
  130.      *
  131.      * @return \Doctrine\DBAL\Result|\Doctrine\DBAL\Driver\ResultStatement|null
  132.      *
  133.      * @throws ValidationException
  134.      */
  135.     public static function queryIgnoreError(ConnectionInterface|\Doctrine\DBAL\Connection $db$sql$exclusions = [])
  136.     {
  137.         try {
  138.             return $db->executeQuery($sql);
  139.         } catch (\Exception $e) {
  140.             foreach ($exclusions as $exclusion) {
  141.                 if ($e instanceof $exclusion) {
  142.                     throw new ValidationException($e->getMessage(), 0$e);
  143.                 }
  144.             }
  145.             // we simply ignore the error
  146.         }
  147.         return null;
  148.     }
  149.     /**
  150.      * @param ConnectionInterface|\Doctrine\DBAL\Connection $db
  151.      * @param string $text
  152.      * @param mixed $value
  153.      * @param int|string|Type|null $type
  154.      * @param int|null $count
  155.      *
  156.      * @return array|string
  157.      */
  158.     public static function quoteInto(ConnectionInterface|\Doctrine\DBAL\Connection $db$text$value$type null$count null)
  159.     {
  160.         if ($count === null) {
  161.             return str_replace('?'$db->quote($value$type), $text);
  162.         }
  163.         return implode($db->quote($value$type), explode('?'$text$count 1));
  164.     }
  165.     public static function escapeLike(string $like): string
  166.     {
  167.         return str_replace(['_''%'], ['\\_''\\%'], $like);
  168.     }
  169.     public static function quoteDataIdentifiers(ConnectionInterface|\Doctrine\DBAL\Connection $db, array $data): array
  170.     {
  171.         $newData = [];
  172.         foreach ($data as $key => $value) {
  173.             $newData[$db->quoteIdentifier($key)] = $value;
  174.         }
  175.         return $newData;
  176.     }
  177. }