supernova-ws /
SuperNova
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | |||
| 3 | /** |
||
| 4 | * Created by Gorlum 31.07.2016 12:08 |
||
| 5 | */ |
||
| 6 | |||
| 7 | namespace DBAL; |
||
| 8 | |||
| 9 | use \classSupernova; |
||
| 10 | use \SnCache; |
||
| 11 | use \db_mysql; |
||
| 12 | |||
| 13 | class DbTransaction { |
||
| 14 | |||
| 15 | protected $db_in_transaction = false; |
||
| 16 | protected $transaction_id = 0; |
||
| 17 | |||
| 18 | /** |
||
| 19 | * @var db_mysql $db |
||
| 20 | */ |
||
| 21 | protected $db; |
||
| 22 | |||
| 23 | /** |
||
| 24 | * DbTransaction constructor. |
||
| 25 | * |
||
| 26 | * @param db_mysql $db |
||
| 27 | */ |
||
| 28 | public function __construct($db) { |
||
| 29 | $this->db = $db; |
||
| 30 | } |
||
| 31 | |||
| 32 | /** |
||
| 33 | * Эта функция проверяет статус транзакции |
||
| 34 | * |
||
| 35 | * Это - низкоуровневая функция. В нормальном состоянии движка её сообщения никогда не будут видны |
||
| 36 | * |
||
| 37 | * @param null|true|false $status Должна ли быть запущена транзакция в момент проверки |
||
| 38 | * <p>null - транзакция НЕ должна быть запущена</p> |
||
| 39 | * <p>true - транзакция должна быть запущена - для совместимости с $for_update</p> |
||
| 40 | * <p>false - всё равно - для совместимости с $for_update</p> |
||
| 41 | * |
||
| 42 | * @return bool Текущий статус транзакции |
||
| 43 | */ |
||
| 44 | public function check($status = null) { |
||
| 45 | $error_msg = false; |
||
| 46 | if ($status && !$this->db_in_transaction) { |
||
| 47 | $error_msg = 'No transaction started for current operation'; |
||
| 48 | } elseif ($status === null && $this->db_in_transaction) { |
||
| 49 | $error_msg = 'Transaction is already started'; |
||
| 50 | } |
||
| 51 | |||
| 52 | if (!empty($error_msg)) { |
||
| 53 | // TODO - Убрать позже |
||
| 54 | print('<h1>СООБЩИТЕ ЭТО АДМИНУ: sn_db_transaction_check() - ' . $error_msg . '</h1>'); |
||
| 55 | $backtrace = debug_backtrace(); |
||
| 56 | array_shift($backtrace); |
||
| 57 | pdump($backtrace); |
||
| 58 | die($error_msg); |
||
| 59 | } |
||
| 60 | |||
| 61 | return $this->db_in_transaction; |
||
| 62 | } |
||
| 63 | |||
| 64 | public function start($level = '') { |
||
| 65 | $this->check(null); |
||
| 66 | |||
| 67 | $level ? $this->db->doExecute('SET TRANSACTION ISOLATION LEVEL ' . $level) : false; |
||
| 68 | |||
| 69 | $this->transaction_id++; |
||
| 70 | $this->db->doExecute('START TRANSACTION'); |
||
| 71 | |||
| 72 | if (classSupernova::$gc->config->db_manual_lock_enabled) { |
||
| 73 | classSupernova::$gc->config->db_loadItem('var_db_manually_locked'); |
||
|
0 ignored issues
–
show
|
|||
| 74 | classSupernova::$gc->config->db_saveItem('var_db_manually_locked', SN_TIME_SQL); |
||
|
0 ignored issues
–
show
The method
db_saveItem does only exist in classConfig, but not in Closure.
It seems like the method you are trying to call exists only in some of the possible types. Let’s take a look at an example: class A
{
public function foo() { }
}
class B extends A
{
public function bar() { }
}
/**
* @param A|B $x
*/
function someFunction($x)
{
$x->foo(); // This call is fine as the method exists in A and B.
$x->bar(); // This method only exists in B and might cause an error.
}
Available Fixes
Loading history...
|
|||
| 75 | } |
||
| 76 | |||
| 77 | $this->db_in_transaction = true; |
||
| 78 | SnCache::locatorReset(); |
||
| 79 | SnCache::queriesReset(); |
||
| 80 | |||
| 81 | return $this->transaction_id; |
||
| 82 | } |
||
| 83 | |||
| 84 | // TODO - move changeset data and methods somewhere |
||
| 85 | public function commit() { |
||
| 86 | $this->check(true); |
||
|
0 ignored issues
–
show
true is of type boolean, but the function expects a null|object<DBAL\true>|false.
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
Loading history...
|
|||
| 87 | |||
| 88 | if (!empty(classSupernova::$delayed_changset)) { |
||
| 89 | classSupernova::db_changeset_apply(classSupernova::$delayed_changset, true); |
||
| 90 | } |
||
| 91 | $this->db->doExecute('COMMIT'); |
||
| 92 | |||
| 93 | return $this->db_transaction_clear(); |
||
| 94 | } |
||
| 95 | |||
| 96 | public function rollback() { |
||
| 97 | // TODO - вообще-то тут тоже надо проверять есть ли транзакция |
||
| 98 | |||
| 99 | if (!empty(classSupernova::$delayed_changset)) { |
||
| 100 | // TODO Для этапа 1 - достаточно чистить только те таблицы, что были затронуты |
||
| 101 | // Для этапа 2 - чистить только записи |
||
| 102 | // Для этапа 3 - возвращать всё |
||
| 103 | SnCache::cache_clear_all(true); |
||
| 104 | } |
||
| 105 | $this->db->doExecute('ROLLBACK'); |
||
| 106 | |||
| 107 | return $this->db_transaction_clear(); |
||
| 108 | } |
||
| 109 | |||
| 110 | protected function db_transaction_clear() { |
||
| 111 | classSupernova::$delayed_changset = array(); |
||
| 112 | SnCache::cache_lock_unset_all(); |
||
| 113 | |||
| 114 | $this->db_in_transaction = false; |
||
| 115 | $this->transaction_id++; |
||
| 116 | |||
| 117 | return $this->transaction_id; |
||
| 118 | } |
||
| 119 | |||
| 120 | /** |
||
| 121 | * Get Transaction ID for next query |
||
| 122 | * |
||
| 123 | * If transaction is in progress - next ID would be equal to current |
||
| 124 | * Otherwise we should increase ID and return this value |
||
| 125 | * |
||
| 126 | * @return int |
||
| 127 | */ |
||
| 128 | public function getNextQueryTransactionId() { |
||
| 129 | return $this->check(false) ? $this->transaction_id : $this->transaction_id++; |
||
| 130 | } |
||
| 131 | |||
| 132 | } |
||
| 133 |
It seems like the method you are trying to call exists only in some of the possible types.
Let’s take a look at an example:
Available Fixes
Add an additional type-check:
Only allow a single type to be passed if the variable comes from a parameter: