Server IP : 184.154.167.98 / Your IP : 3.138.137.175 Web Server : Apache System : Linux pink.dnsnetservice.com 4.18.0-553.22.1.lve.1.el8.x86_64 #1 SMP Tue Oct 8 15:52:54 UTC 2024 x86_64 User : puertode ( 1767) PHP Version : 8.2.26 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : ON Directory : /home/puertode/public_html/mesa/include/ |
Upload File : |
<?php require_once INCLUDE_DIR . 'class.orm.php'; class Sequence extends VerySimpleModel { static $meta = array( 'table' => SEQUENCE_TABLE, 'pk' => array('id'), 'ordering' => array('name'), ); const FLAG_INTERNAL = 0x0001; /** * Function: next * * Fetch the next number in the sequence. The next number in the * sequence will be adjusted in the database so that subsequent calls to * this function should never receive the same result. * * Optionally, a format specification can be sent to the function and * the next sequence number will be returned padded. See the `::format` * function for more details. * * Optionally, a check callback can be specified to ensure the next * value of the sequence is valid. This might be useful for a * pseudo-random generator which might repeat existing numbers. The * callback should have the following signature and should return * boolean TRUE to approve the number. * * Parameters: * $format - (string) Format specification for the result * $check - (function($format, $next)) Validation callback function * where $next will be the next value as an integer, and $formatted * will be the formatted version of the number, if a $format * parameter were passed to the `::next` method. * * Returns: * (int|string) - next number in the sequence, optionally formatted and * verified. */ function next($format=false, $check=false) { $digits = $format ? $this->getDigitCount($format) : false; if ($check && !is_callable($check)) $check = false; do { $next = $this->__next($digits); $formatted = $format ? $this->format($format, $next) : $next; } while ($check && !call_user_func_array($check, array($formatted, $next))); return $formatted; } /** * Function: current * * Peeks at the next number in the sequence without incrementing the * sequence. * * Parameters: * $format - (string:optional) format string to receive the current * sequence number * * Returns: * (int|string) - the next number in the sequence without advancing the * sequence, optionally formatted. See the `::format` method for * formatting details. */ function current($format=false) { return $format ? $this->format($format, $this->next) : $this->next; } /** * Function: format * * Formats a number to the given format. The number will be placed into * the format string according to the locations of hash characters (#) * in the string. If more hash characters are encountered than digits * the digits are left-padded accoring to the sequence padding * character. If fewer are found, the last group will receive all the * remaining digits. * * Hash characters can be escaped with a backslash (\#) and will emit a * single hash character to the output. * * Parameters: * $format - (string) Format string for the number, e.g. "TX-######-US" * $number - (int) Number to appear in the format. If not * specified the next number in this sequence will be used. */ function format($format, $number) { $groups = array(); preg_match_all('/(?<!\\\)#+/', $format, $groups, PREG_OFFSET_CAPTURE); $total = 0; foreach ($groups[0] as $g) $total += strlen($g[0]); $number = str_pad($number, $total, $this->padding, STR_PAD_LEFT); $output = ''; $start = $noff = 0; // Interate through the ### groups and replace the number of hash // marks with numbers from the sequence foreach ($groups[0] as $g) { $size = strlen($g[0]); // Add format string from previous marker to current ## group $output .= str_replace('\#', '#', substr($format, $start, $g[1] - $start)); // Add digits from the sequence number $output .= substr($number, $noff, $size); // Set offset counts for the next loop $start = $g[1] + $size; $noff += $size; } // If there are more digits of number than # marks, add the number // where the last hash mark was found if (strlen($number) > $noff) $output .= substr($number, $noff); // Add format string from ending ## group $output .= str_replace('\#', '#', substr($format, $start)); return $output; } function getDigitCount($format) { $total = 0; $groups = array(); return preg_match_all('/(?<!\\\)#/', $format, $groups); } /** * Function: __next * * Internal implementation of the next number generator. This method * will lock the database object backing to protect against concurent * ticket processing. The lock will be released at the conclusion of the * session. * * Parameters: * $digits - (int:optional) number of digits (size) of the number. This * is useful for random sequences which need a size hint to * generate a "next" value. * * Returns: * (int) - The current number in the sequence. The sequence is advanced * and assured to be session-wise atomic before the value is returned. */ function __next($digits=false) { // Ensure this block is executed in a single transaction db_autocommit(false); // Lock the database object -- this is important to handle concurrent // requests for new numbers static::objects()->filter(array('id'=>$this->id))->lock()->one(); // Increment the counter $next = $this->next; $this->next += $this->increment; $this->updated = SqlFunction::NOW(); $this->save(); db_autocommit(true); return $next; } function hasFlag($flag) { return $this->flags & $flag != 0; } function setFlag($flag, $value=true) { if ($value) $this->flags |= $flag; else $this->flags &= ~$flag; } function getName() { return $this->name; } function isValid() { if (!$this->name) return 'Name is required'; if (!$this->increment) return 'Non-zero increment is required'; if (!$this->next || $this->next < 0) return 'Positive "next" value is required'; if (!$this->padding) $this->padding = '0'; return true; } function __get($what) { // Pseudo-property for $sequence->current if ($what == 'current') return $this->current(); return parent::__get($what); } static function __create($data) { $instance = new self($data); $instance->save(); return $instance; } } class RandomSequence extends Sequence { var $padding = '0'; function __next($digits=6) { if ($digits < 6) $digits = 6; return Misc::randNumber($digits); } function current($format=false) { return $this->next($format); } function save($refetch=false) { throw new RuntimeException('RandomSequence is not database-backed'); } }