コード例 #1
0
ファイル: Debugger.php プロジェクト: sintattica/atk
 /**
  * Get an instance of this class.
  *
  * @return Debugger Instance of atkDebugger
  */
 public static function getInstance()
 {
     static $s_instance = null;
     if ($s_instance == null) {
         if (!SessionManager::getInstance()) {
             Tools::atkwarning('Instantiating debugger without sessionmanager, debugger will not do anything until session is started. Also, the debugging info already in the session will not be cleaned, this could lead to monster sessions over time!');
         }
         $s_instance = new self();
     }
     return $s_instance;
 }
コード例 #2
0
ファイル: CountryAttribute.php プロジェクト: sintattica/atk
 /**
  * With this function you can set the "custom" list with a array of country ISO codes
  * that are KNOWN to this class. (they should be in the world list atleast).
  *
  * @param array $countries CountryIso codes, like NL BE LU etc...
  *
  * @return bool It will return false when the resulting custom list is empty.
  */
 public function setList($countries)
 {
     $custom_list = [];
     foreach ($countries as $countryIso) {
         $countryIso = strtoupper($countryIso);
         if (in_array($countryIso, $this->m_world_countries)) {
             array_push($custom_list, $countryIso);
         } else {
             Tools::atkwarning('atkCountryAttribute: setList: ' . $countryIso . ' is a unknown country and will be ignored');
         }
     }
     if (count($custom_list) == 0) {
         Tools::atkerror('atkCountryAttribute: setList: empty custom country list');
         return false;
     }
     $this->m_custom_countries = $custom_list;
     return true;
 }
コード例 #3
0
ファイル: TmpFile.php プロジェクト: sintattica/atk
 /**
  * Set the base directory for writing
  * instead of the default atktmp dir.
  *
  * @param string $dir base directory
  *
  * @return bool
  */
 public function setBasedir($dir)
 {
     if (!is_dir($dir) || !is_writable($dir)) {
         $err = 'TmpFile:: Unable to set ' . $dir . 'as basedir. Directory does not exists or isnot writable';
         Tools::atkwarning($err);
         return false;
     }
     $this->m_basedir = $dir;
     return true;
 }
コード例 #4
0
ファイル: SessionStore.php プロジェクト: sintattica/atk
 /**
  * Check if the given row key is valid.
  *
  * @param int $rowKey Row key
  * @param array $data Data array
  *
  * @return bool
  */
 private static function isValidRowKey($rowKey, $data)
 {
     if ($rowKey === false) {
         Tools::atkwarning(__CLASS__ . '->' . __METHOD__ . ': No row key selector found');
         return false;
     } elseif (!array_key_exists($rowKey, $data)) {
         Tools::atkwarning(__CLASS__ . '->' . __METHOD__ . ': Row key not found in the data');
         return false;
     }
     return true;
 }
コード例 #5
0
ファイル: MySqliDb.php プロジェクト: sintattica/atk
 /**
  * Get all MySQL warnings for the previously executed query
  * and make atkwarnings of them.
  */
 public function debugWarnings()
 {
     $stmt = $this->_query('SHOW WARNINGS', true);
     $warnings = [];
     while ($warning = $stmt->fetch_assoc()) {
         $warnings[] = $warning;
     }
     foreach ($warnings as $warning) {
         Tools::atkwarning("MYSQL warning '{$warning['Level']}' (Code: {$warning['Code']}): {$warning['Message']}");
     }
 }
コード例 #6
0
ファイル: SessionManager.php プロジェクト: sintattica/atk
 /**
  * Removes any stacks which have been inactive for a period >
  * Config::getGlobal('session_max_stack_inactivity_period').
  */
 protected function _removeExpiredStacks()
 {
     $sessionData =& self::getSession();
     $maxAge = Config::getGlobal('session_max_stack_inactivity_period', 0);
     if ($maxAge <= 0) {
         Tools::atkwarning(__METHOD__ . ': removing expired stacks disabled, enable by setting $config_session_max_stack_inactivity_period to a value > 0');
         return;
     }
     $now = time();
     $stacks =& $sessionData[$this->m_namespace]['stack'];
     $stackStamps = $sessionData[$this->m_namespace]['stack_stamp'];
     $stackIds = array_keys($stacks);
     $removed = false;
     foreach ($stackIds as $stackId) {
         // don't remove the current stack or stacks that are, for some reason, not stamped
         if ($stackId == $this->atkStackID() || !isset($stackStamps[$stackId])) {
             continue;
         }
         $stamp = $stackStamps[$stackId];
         $age = $now - $stamp;
         if ($age > $maxAge) {
             Tools::atkdebug(__METHOD__ . ': removing expired stack "' . $stackId . '" (age ' . $age . 's)');
             unset($stacks[$stackId]);
             unset($stackStamps[$stackId]);
             $removed = true;
         }
     }
     if (!$removed) {
         Tools::atkdebug(__METHOD__ . ': no expired stacks, nothing removed');
     }
 }
コード例 #7
0
ファイル: Node.php プロジェクト: sintattica/atk
 /**
  * Delete record(s) from the database.
  *
  * After deletion, the postDel() trigger in the node method is called, and
  * on any attribute that has the Attribute::AF_CASCADE_DELETE flag set, the delete()
  * method is invoked.
  *
  * NOTE: Does not commit your transaction! If you are using a database that uses
  * transactions you will need to call 'Db::getInstance()->commit()' manually.
  *
  * @todo There's a discrepancy between updateDb, addDb and deleteDb:
  *       There should be a deleteDb which accepts a record, instead
  *       of a selector.
  *
  * @param string $selector SQL expression used as where-clause that
  *                              indicates which records to delete.
  * @param bool $exectrigger wether to execute the pre/post triggers
  * @param bool $failwhenempty determine whether to throw an error if there is nothing to delete
  * @returns boolean True if successful, false if not.
  */
 public function deleteDb($selector, $exectrigger = true, $failwhenempty = false)
 {
     $recordset = $this->select($selector)->mode('delete')->getAllRows();
     // nothing to delete, throw an error (determined by $failwhenempty)!
     if (count($recordset) == 0) {
         Tools::atkwarning($this->atkNodeUri() . "->deleteDb({$selector}): 0 records found, not deleting anything.");
         return !$failwhenempty;
     }
     if ($exectrigger) {
         for ($i = 0, $_i = count($recordset); $i < $_i; ++$i) {
             $return = $this->executeTrigger('preDelete', $recordset[$i]);
             if (!$return) {
                 return false;
             }
         }
     }
     // delete on "cascading" attributes (like relations, file attribute) BEFORE the query execution
     if (count($this->m_cascadingAttribs) > 0) {
         for ($i = 0, $_i = count($recordset); $i < $_i; ++$i) {
             for ($j = 0, $_j = count($this->m_cascadingAttribs); $j < $_j; ++$j) {
                 $p_attrib = $this->m_attribList[$this->m_cascadingAttribs[$j]];
                 if (isset($recordset[$i][$this->m_cascadingAttribs[$j]]) && !$p_attrib->isEmpty($recordset[$i])) {
                     if (!$p_attrib->delete($recordset[$i])) {
                         // error
                         return false;
                     }
                 }
             }
         }
     }
     $query = $this->getDb()->createQuery();
     $query->addTable($this->m_table);
     $query->addCondition($selector);
     if ($query->executeDelete()) {
         // postDelete on "cascading" attributes (like relations, file attribute) AFTER the query execution
         if (count($this->m_cascadingAttribs) > 0) {
             for ($i = 0, $_i = count($recordset); $i < $_i; ++$i) {
                 for ($j = 0, $_j = count($this->m_cascadingAttribs); $j < $_j; ++$j) {
                     $p_attrib = $this->m_attribList[$this->m_cascadingAttribs[$j]];
                     if (isset($recordset[$i][$this->m_cascadingAttribs[$j]]) && !$p_attrib->isEmpty($recordset[$i])) {
                         if (!$p_attrib->postDelete($recordset[$i])) {
                             // error
                             return false;
                         }
                     }
                 }
             }
         }
         if ($exectrigger) {
             for ($i = 0, $_i = count($recordset); $i < $_i; ++$i) {
                 $return = $this->executeTrigger('postDel', $recordset[$i]) && $this->executeTrigger('postDelete', $recordset[$i]);
                 if (!$return) {
                     return false;
                 }
             }
         }
         return true;
     } else {
         return false;
     }
 }
コード例 #8
0
ファイル: FileAttribute.php プロジェクト: sintattica/atk
 /**
  * Returns a piece of html code that can be used in a form to edit this
  * attribute's value.
  *
  * @param array $record Record
  * @param string $fieldprefix Field prefix
  * @param string $mode The mode we're in ('add' or 'edit')
  *
  * @return string piece of html code with a browsebox
  */
 public function edit($record, $fieldprefix, $mode)
 {
     $result = '';
     // When in add mode or we have errors, don't show the filename above the input.
     $hasErrors = isset($record[$this->fieldName()]['error']) && $record[$this->fieldName()]['error'] != 0;
     if ($mode != 'add' && !$hasErrors) {
         if (method_exists($this->getOwnerInstance(), $this->fieldName() . '_display')) {
             $method = $this->fieldName() . '_display';
             $result = $this->m_ownerInstance->{$method}($record, 'view');
         } else {
             $result = $this->display($record, $mode);
         }
     }
     if (!is_dir($this->m_dir) || !is_writable($this->m_dir)) {
         Tools::atkwarning('atkFileAttribute: ' . $this->m_dir . ' does not exist or is not writeable');
         return Tools::atktext('no_valid_directory', 'atk') . ': ' . $this->m_dir;
     }
     $id = $this->getHtmlId($fieldprefix);
     $name = $this->getHtmlName($fieldprefix);
     if (isset($record[$this->fieldName()]['orgfilename'])) {
         $result .= '<br />';
         $result .= '<input type="hidden" name="' . $name . '_orgfilename" value="' . $record[$this->fieldName()]['orgfilename'] . '">';
     }
     $onchange = '';
     if (count($this->m_onchangecode)) {
         $onchange = ' onChange="' . $id . '_onChange(this);"';
         $this->_renderChangeHandler($fieldprefix);
     }
     if (!$this->hasFlag(self::AF_FILE_NO_UPLOAD)) {
         $result .= '<input type="file" id="' . $id . '" name="' . $name . '" ' . $onchange . '>';
     }
     if (!$this->hasFlag(self::AF_FILE_NO_SELECT)) {
         $file_arr = $this->getFiles($this->m_dir);
         if (count($file_arr) > 0) {
             natcasesort($file_arr);
             $result .= '<select id="' . $id . '_select" name="' . $name . '[select]" ' . $onchange . ' class="form-control select-standard">';
             // Add default option with value NULL
             $result .= '<option value="" selected>' . Tools::atktext('selection', 'atk');
             while (list(, $val) = each($file_arr)) {
                 isset($record[$this->fieldName()]['filename']) && $record[$this->fieldName()]['filename'] == $val ? $selected = 'selected' : ($selected = '');
                 if (is_file($this->m_dir . $val)) {
                     $result .= '<option value="' . $val . "\" {$selected}>" . $val;
                 }
             }
             $result .= '</select>';
         }
     } else {
         if (isset($record[$this->fieldName()]['filename']) && !empty($record[$this->fieldName()]['filename'])) {
             $result .= '<input type="hidden" name="' . $name . '[select]" value="' . $record[$this->fieldName()]['filename'] . '">';
         }
     }
     if (!$this->hasFlag(self::AF_FILE_NO_DELETE) && isset($record[$this->fieldName()]['orgfilename']) && $record[$this->fieldName()]['orgfilename'] != '') {
         $result .= '<br class="atkFileAttributeCheckboxSeparator"><input id="' . $id . '_del" type="checkbox" name="' . $name . '[del]" ' . $this->getCSSClassAttribute('atkcheckbox') . '>&nbsp;' . Tools::atktext('remove_current_file', 'atk');
     }
     return $result;
 }
コード例 #9
0
 /**
  * This method returns the HTML for the link of a certain action.
  *
  * @param string $action
  * @param array $record
  *
  * @return string
  */
 protected function getActionLink($action, $record)
 {
     $actionMethod = "get{$action}ActionLink";
     if (method_exists($this, $actionMethod)) {
         return $this->{$actionMethod}($record);
     } else {
         Tools::atkwarning('Missing ' . $actionMethod . ' method on manytomanyselectrelation. ');
     }
 }
コード例 #10
0
ファイル: NumberAttribute.php プロジェクト: sintattica/atk
 /**
  * Formats the number based on setting in the language file.
  *
  * @param float $number number
  * @param string $decimalSeparator override decimal separator
  * @param string $thousandsSeparator override thousands separator
  * @param string $mode
  *
  * @return string nicely formatted number
  */
 protected function formatNumber($number, $decimalSeparator = '', $thousandsSeparator = '', $mode = '')
 {
     $decimalSeparator = $decimalSeparator == null ? $this->m_decimalseparator : $decimalSeparator;
     $thousandsSeparator = $thousandsSeparator == null ? $this->m_thousandsseparator : $thousandsSeparator;
     // (never shows the thousands separator in add/edit mode)
     $thousandsSeparator = $this->m_use_thousands_separator && !in_array($mode, array('add', 'edit')) ? $thousandsSeparator : '';
     if ($decimalSeparator == $thousandsSeparator) {
         Tools::atkwarning('invalid thousandsseparator. identical to the decimal_separator');
         $thousandsSeparator = '';
     }
     // NOTE: we don't use number_format because this sometimes causes rounding issues
     //       if a float can not be properly represented (see http://nl.php.net/manual/en/function.number-format.php#93893)
     $tmp1 = abs(round((double) $number, $this->getDecimals()));
     $tmp1 .= $this->getDecimals() > 0 && strpos($tmp1, '.') === false ? '.' : '';
     $tmp1 .= str_repeat('0', max($this->getDecimals() - strlen(substr($tmp1, strpos($tmp1, '.') + 1)), 0));
     while (($tmp2 = preg_replace('/(?<!.)(\\d+)(\\d\\d\\d)/', '\\1 \\2', $tmp1)) != $tmp1) {
         $tmp1 = $tmp2;
     }
     $r = strtr($tmp1, array(' ' => $thousandsSeparator, '.' => $decimalSeparator));
     if ($number < 0) {
         $r = '-' . $r;
     }
     if (!$this->m_trailingzeros) {
         // remove trailing zeros
         if (strpos($r, $decimalSeparator)) {
             $r = rtrim($r, '0');
             $r = rtrim($r, $decimalSeparator);
         }
     }
     return $r;
 }
コード例 #11
0
ファイル: Db.php プロジェクト: sintattica/atk
 /**
  * Get a database instance (singleton)
  *
  * This method instantiates and returns the correct (vendor specific)
  * database instance, depending on the configuration.
  *
  * @static
  *
  * @param string $conn The name of the connection as defined in the
  *                      config.inc.php file (defaults to 'default')
  * @param bool $reset Reset the instance to force the creation of a new instance
  * @param string $mode The mode to connect with the database
  *
  * @return Db Instance of the database class.
  */
 public static function getInstance($conn = 'default', $reset = false, $mode = 'rw')
 {
     static $s_dbInstances = null;
     if ($s_dbInstances == null) {
         $s_dbInstances = [];
         if (!Config::getGlobal('meta_caching')) {
             Tools::atkwarning("Table metadata caching is disabled. Turn on \$config_meta_caching to improve your application's performance!");
         }
     }
     // Resolve any potential aliases
     $conn = self::getTranslatedDatabaseName($conn);
     $dbInstance = array_key_exists($conn, $s_dbInstances) ? $s_dbInstances[$conn] : null;
     if ($reset || !$dbInstance || !$dbInstance->hasMode($mode)) {
         $dbconfig = Config::getGlobal('db');
         $driver = __NAMESPACE__ . '\\' . $dbconfig[$conn]['driver'] . 'Db';
         Tools::atkdebug("Creating new database instance with '{$driver}' driver");
         /** @var Db $driverInstance */
         $driverInstance = new $driver();
         $dbInstance = $driverInstance->init($conn, $mode);
         $s_dbInstances[$conn] = $dbInstance;
     }
     return $dbInstance;
 }