Ejemplo n.º 1
0
 /**
  * This is the actual trigger that moves the record to the recycle bin table.
  *
  * @param array $record The record that is being deleted
  *
  * @return false if there was an error, true if everything is ok
  */
 public function preDelete($record)
 {
     Tools::atkdebug('delete performed, storing record in recyclebin');
     if (isset($this->_options['node'])) {
         $atk = Atk::getInstance();
         $node = $atk->atkGetNode($this->_options['node']);
         $node->addDb($record);
     } else {
         $node = clone $this->m_node;
         $pkFields = $node->m_primaryKey;
         foreach ($pkFields as $fieldName) {
             // We need to make sure the record in the bin has the same primary key as the original
             // record, so we remove Attribute::AF_AUTOINCREMENT and setForceInsert.
             $node->getAttribute($fieldName)->setForceInsert(true)->removeFlag(Attribute::AF_AUTO_INCREMENT);
         }
         if (isset($this->_options['table'])) {
             $node->setTable($this->_options['table']);
         } else {
             // default behaviour: assume table with _bin appendix
             $node->setTable($node->getTable() . '_bin');
         }
         Tools::atkdebug('adding record to recyclebin');
         $node->addDb($record);
     }
     return true;
 }
Ejemplo n.º 2
0
 /**
  * This function renders the url that is used by
  * AdminHandler::getAddLink().
  *
  * @return string The url for the add link for the admin page
  */
 public function getAddUrl()
 {
     $atk = Atk::getInstance();
     $node = $atk->atkGetNode($this->invoke('getAddNodeType'));
     return Config::getGlobal('dispatcher') . '?atknodeuri=' . $node->atkNodeUri() . '&atkaction=add';
 }
Ejemplo n.º 3
0
 /**
  * Create the instance of the destination.
  *
  * If succesful, the instance is stored in the m_destInstance member variable.
  *
  * @return bool true if succesful, false if something went wrong.
  */
 public function createDestination()
 {
     if (!is_object($this->m_destInstance)) {
         $atk = Atk::getInstance();
         $cache_id = $this->m_owner . '.' . $this->m_name;
         $this->m_destInstance = $atk->atkGetNode($this->m_destination, true, $cache_id);
         // Validate if destination was created succesfully
         if (!is_object($this->m_destInstance)) {
             Tools::atkerror("Relation with unknown nodetype '" . $this->m_destination . "' (in node '" . $this->m_owner . "')");
             $this->m_destInstance = null;
             return false;
         }
         if ($this->hasFlag(self::AF_NO_FILTER)) {
             $this->m_destInstance->m_flags |= Node::NF_NO_FILTER;
         }
         foreach (array_keys($this->m_destInstance->m_attribList) as $key) {
             $attribute = $this->m_destInstance->m_attribList[$key];
             if (is_subclass_of($attribute, 'Relation') && is_object($this->m_ownerInstance) && $attribute->m_destination == $this->m_ownerInstance->atkNodeUri()) {
                 $attribute->m_destInstance = $this->m_ownerInstance;
                 if (count($attribute->m_tabs) == 1 && $attribute->m_tabs[0] == 'default') {
                     $attribute->setTabs($this->m_tabs);
                 }
             }
         }
         if (!empty($this->m_descHandler)) {
             $this->m_destInstance->setDescriptorHandler($this);
         }
         if (!empty($this->m_descTemplate)) {
             $this->m_destInstance->setDescriptorTemplate($this->m_descTemplate);
         }
     }
     return true;
 }
Ejemplo n.º 4
0
 /**
  * The delete method is called by the framework to inform the attribute
  * that the master record is deleted.
  *
  * Note that the framework only calls the method when the
  * self::AF_CASCADE_DELETE flag is set. When calling this method, the detail
  * record belonging to the master record is deleted.
  *
  * @param array $record The record that is deleted.
  *
  * @return bool true if cleanup was successful, false otherwise.
  */
 public function delete($record)
 {
     $atk = Atk::getInstance();
     $classname = $this->m_destination;
     $cache_id = $this->m_owner . '.' . $this->m_name;
     $rel = $atk->atkGetNode($classname, true, $cache_id);
     Tools::atkdebug("O2O DELETE for {$classname}: " . $this->m_refKey . '=' . $record[$this->m_ownerInstance->primaryKeyField()]);
     if ($this->m_refKey != '') {
         // Foreign key is in the destination node
         $condition = $rel->m_table . '.' . $this->m_refKey . '=' . $this->m_ownerInstance->m_attribList[$this->m_ownerInstance->primaryKeyField()]->value2db($record);
     } else {
         // Foreign key is in the source node.
         $condition = $rel->m_table . '.' . $rel->m_primaryKey[0] . '=' . $record[$this->fieldName()][$this->m_ownerInstance->primaryKeyField()];
     }
     return $rel->deleteDb($condition);
 }
Ejemplo n.º 5
0
 /**
  * Handle the error.
  *
  * @param string $errorMessage
  * @param string $debugMessage
  */
 public function handle($errorMessage, $debugMessage)
 {
     $sessionManager = SessionManager::getInstance();
     $sessionData =& SessionManager::getSession();
     $txt_app_title = Tools::atktext('app_title');
     if ($this->params['mailto'] != '') {
         // only if enabled..
         $atk = Atk::getInstance();
         $subject = '[' . $_SERVER['SERVER_NAME'] . "] {$txt_app_title} error";
         $defaultfrom = sprintf('%s <%s@%s>', $txt_app_title, Config::getGlobal('identifier', 'atk'), $_SERVER['SERVER_NAME']);
         $from = Config::getGlobal('mail_sender', $defaultfrom);
         $body = "Hello,\n\nAn error seems to have occurred in the atk application named '{$txt_app_title}'.\n";
         $body .= "\nThe errormessage was:\n\n" . implode("\n", is_array($errorMessage) ? $errorMessage : array()) . "\n";
         $body .= "\nA detailed report follows:\n";
         $body .= "\nPHP Version: " . phpversion() . "\n\n";
         $body .= "\nDEBUGMESSAGES\n" . str_repeat('-', 70) . "\n";
         $lines = [];
         for ($i = 0, $_ = count($debugMessage); $i < $_; ++$i) {
             $lines[] = $this->_wordwrap(Tools::atk_html_entity_decode(preg_replace('(\\[<a.*</a>\\])', '', $debugMessage[$i])));
         }
         $body .= implode("\n", $lines);
         if (is_array($_GET)) {
             $body .= "\n\n_GET\n" . str_repeat('-', 70) . "\n";
             foreach ($_GET as $key => $value) {
                 $body .= $this->_wordwrap($key . str_repeat(' ', max(1, 20 - strlen($key))) . ' = ' . var_export($value, 1)) . "\n";
             }
         }
         if (function_exists('getallheaders')) {
             $request = getallheaders();
             if (count($request) > 0) {
                 $body .= "\n\nREQUEST INFORMATION\n" . str_repeat('-', 70) . "\n";
                 foreach ($request as $key => $value) {
                     $body .= $this->_wordwrap($key . str_repeat(' ', max(1, 30 - strlen($key))) . ' = ' . var_export($value, 1)) . "\n";
                 }
             }
         }
         if (is_array($_POST)) {
             $body .= "\n\n_POST\n" . str_repeat('-', 70) . "\n";
             foreach ($_POST as $key => $value) {
                 $body .= $this->_wordwrap($key . str_repeat(' ', max(1, 20 - strlen($key))) . ' = ' . var_export($value, 1)) . "\n";
             }
         }
         if (is_array($_COOKIE)) {
             $body .= "\n\n_COOKIE\n" . str_repeat('-', 70) . "\n";
             foreach ($_COOKIE as $key => $value) {
                 $body .= $this->_wordwrap($key . str_repeat(' ', max(1, 20 - strlen($key))) . ' = ' . var_export($value, 1)) . "\n";
             }
         }
         $body .= "\n\nATK CONFIGURATION\n" . str_repeat('-', 70) . "\n";
         foreach ($GLOBALS as $key => $value) {
             if (substr($key, 0, 7) == 'config_') {
                 $body .= $this->_wordwrap($key . str_repeat(' ', max(1, 30 - strlen($key))) . ' = ' . var_export($value, 1)) . "\n";
             }
         }
         $body .= "\n\nMODULE CONFIGURATION\n" . str_repeat('-', 70) . "\n";
         foreach ($atk->g_modules as $modname => $modpath) {
             $modexists = file_exists($modpath) ? ' (path exists)' : ' (PATH DOES NOT EXIST!)';
             $body .= $this->_wordwrap($modname . ':' . str_repeat(' ', max(1, 20 - strlen($modname))) . var_export($modpath, 1) . $modexists) . "\n";
         }
         $body .= "\n\nCurrent User:\n" . str_repeat('-', 70) . "\n";
         $user = SecurityManager::atkGetUser();
         if (is_array($user) && count($user)) {
             foreach ($user as $key => $value) {
                 $body .= $this->_wordwrap($key . str_repeat(' ', max(1, 30 - strlen($key))) . ' = ' . var_export($value, 1)) . "\n";
             }
         } else {
             $body .= "Not known\n";
         }
         if (is_object($sessionManager)) {
             $body .= "\n\nATK SESSION\n" . str_repeat('-', 70);
             $body .= "\nNamespace: " . $sessionManager->getNameSpace() . "\n";
             if (isset($sessionData[$sessionManager->getNameSpace()]['stack'])) {
                 $stack = $sessionData[$sessionManager->getNameSpace()]['stack'];
                 for ($i = 0; $i < count($stack); ++$i) {
                     $body .= "\nStack level {$i}:\n";
                     $item = isset($stack[$i]) ? $stack[$i] : null;
                     if (is_array($item)) {
                         foreach ($item as $key => $value) {
                             $body .= $this->_wordwrap($key . str_repeat(' ', max(1, 30 - strlen($key))) . ' = ' . var_export($value, 1)) . "\n";
                         }
                     }
                 }
             }
             if (isset($sessionData[$sessionManager->getNameSpace()]['globals'])) {
                 $ns_globals = $sessionData[$sessionManager->getNameSpace()]['globals'];
                 if (count($ns_globals) > 0) {
                     $body .= "\nNamespace globals:\n";
                     foreach ($ns_globals as $key => $value) {
                         $body .= $this->_wordwrap($key . str_repeat(' ', max(1, 30 - strlen($key))) . ' = ' . var_export($value, 1)) . "\n";
                     }
                 }
             }
             if (isset($sessionData['globals'])) {
                 $globals = $sessionData['globals'];
                 if (count($globals) > 0) {
                     $body .= "\nGlobals:\n";
                     foreach ($globals as $key => $value) {
                         $body .= $this->_wordwrap($key . str_repeat(' ', max(1, 30 - strlen($key))) . ' = ' . var_export($value, 1)) . "\n";
                     }
                 }
             }
         }
         $body .= "\n\nSERVER INFORMATION\n" . str_repeat('-', 70) . "\n";
         foreach ($_SERVER as $key => $value) {
             $body .= $this->_wordwrap($key . str_repeat(' ', max(1, 20 - strlen($key))) . ' = ' . var_export($value, 1)) . "\n";
         }
         //TODO: replace with some mailer object
         mail($this->params['mailto'], $subject, $body, "From: {$from}");
     }
 }
Ejemplo n.º 6
0
 /**
  * Gets the node and the descriptor for the current item
  * and returns a trace of that.
  *
  * So for instance, if we were adding a grade to a student,
  * it would show:
  * Student [ Teknoman ] - Grade [ A+ ]
  *
  * @return string The descriptortrace
  */
 public function descriptorTrace()
 {
     $sessionData =& self::getSession();
     $stack = $sessionData[$this->m_namespace]['stack'][$this->atkStackID()];
     $res = [];
     $node = null;
     $module = null;
     $nodename = null;
     $stackcount = count($stack);
     $atk = Atk::getInstance();
     for ($i = 0; $i < $stackcount; ++$i) {
         if (isset($stack[$i]['descriptor']) || $i == $stackcount - 1) {
             if ($stack[$i]['atknodeuri'] != '') {
                 $node = $atk->atkGetNode($stack[$i]['atknodeuri']);
                 $module = Tools::getNodeModule($stack[$i]['atknodeuri']);
                 $nodename = Tools::getNodeType($stack[$i]['atknodeuri']);
             }
             if (is_object($node)) {
                 $ui = Ui::getInstance();
                 $txt = $ui->title($module, $nodename);
             } else {
                 $txt = Tools::atktext($nodename, $module);
             }
             $res[] = $txt . (isset($stack[$i]['descriptor']) ? " [ {$stack[$i]['descriptor']} ] " : '');
         }
     }
     return $res;
 }
Ejemplo n.º 7
0
 /**
  * Are we allowed to delete a record?
  *
  * @return mixed bool if allowed or string with not allowed message
  */
 public function deleteAllowed()
 {
     if ($this->hasFlag(self::AF_RESTRICTED_DELETE)) {
         // Get the destination node
         $classname = $this->m_destination;
         $cache_id = $this->m_owner . '.' . $this->m_name;
         $atk = Atk::getInstance();
         $rel = $atk->atkGetNode($classname, $cache_id);
         // Get the current atkselector
         $where = $this->translateSelector($this->m_ownerInstance->m_postvars['atkselector']);
         if ($where) {
             $childrecords = $rel->select($where)->getAllRows();
             if (!empty($childrecords)) {
                 return Tools::atktext('restricted_delete_error');
             }
         } else {
             return false;
         }
     }
     return true;
 }
Ejemplo n.º 8
0
 /**
  * This function returns password or false, if password can't be retrieve/recreate.
  *
  * @param string $username User for which the password should be regenerated
  *
  * @return mixed string with password or false
  */
 public function gettingPassword($username)
 {
     // Query the database for user records having the given username and return if not found
     $atk = Atk::getInstance();
     $usernode = $atk->atkGetNode(Config::getGlobal('auth_usernode'));
     $selector = sprintf("%s.%s = '%s'", Config::getGlobal('auth_usertable'), Config::getGlobal('auth_userfield'), $username);
     $userrecords = $usernode->select($selector)->mode('edit')->includes(array(Config::getGlobal('auth_userpk'), Config::getGlobal('auth_emailfield'), Config::getGlobal('auth_passwordfield')))->getAllRows();
     if (count($userrecords) != 1) {
         Tools::atkdebug("User '{$username}' not found.");
         return false;
     }
     // Retrieve the email address
     $email = $userrecords[0][Config::getGlobal('auth_emailfield')];
     if (empty($email)) {
         Tools::atkdebug("Email address for '{$username}' not available.");
         return false;
     }
     // Regenerate the password
     /** @var \Sintattica\Atk\Attributes\PasswordAttribute $passwordattr */
     $passwordattr = $usernode->getAttribute(Config::getGlobal('auth_passwordfield'));
     $newpassword = $passwordattr->generatePassword();
     // Update the record in the database
     $userrecords[0][Config::getGlobal('auth_passwordfield')]['hash'] = password_hash($newpassword, PASSWORD_DEFAULT);
     $usernode->updateDb($userrecords[0], true, '', array(Config::getGlobal('auth_passwordfield')));
     $usernode->getDb()->commit();
     // Return true
     return $newpassword;
 }
Ejemplo n.º 9
0
 /**
  * Create instance of the intermediary link node.
  *
  * If succesful, the instance is stored in the m_linkInstance member
  * variable.
  *
  * @return bool True if successful, false if not.
  */
 public function createLink()
 {
     if ($this->m_linkInstance == null) {
         $atk = Atk::getInstance();
         $this->m_linkInstance = $atk->newAtkNode($this->m_link);
         // Validate if destination was created succesfully
         if (!is_object($this->m_linkInstance)) {
             Tools::atkerror("Relation with unknown nodetype '" . $this->m_link . "' (in node '" . $this->m_owner . "')");
             $this->m_linkInstance = null;
             return false;
         }
     }
     return true;
 }
Ejemplo n.º 10
0
 /**
  * Get the atkActionHandler object for a certain action.
  *
  * The default implementation returns a default handler for the action,
  * but derived classes may override this to return a custom handler.
  *
  * @param string $action The action for which the handler is retrieved.
  *
  * @return ActionHandler The action handler.
  */
 public function getHandler($action)
 {
     Tools::atkdebug('self::getHandler(); action: ' . $action);
     //check if a handler exists registered including the module name
     $atk = Atk::getInstance();
     $handler = $atk->atkGetNodeHandler($this->atkNodeUri(), $action);
     // The node handler might return a class, then we need to instantiate the handler
     if (is_string($handler) && class_exists($handler)) {
         $handler = new $handler();
     }
     // The node handler might return a function as nodehandler. We cannot
     // return a function so we ignore this option.
     //       this would probably only work fine when using PHP5, but's better then nothing?
     //       or why support functions at all?!
     // handler object
     if ($handler != null && is_subclass_of($handler, 'ActionHandler')) {
         Tools::atkdebug('self::getHandler: Using existing ActionHandler ' . get_class($handler) . " class for '" . $action . "'");
         $handler->setNode($this);
         $handler->setAction($action);
     } else {
         $handler = ActionHandler::getDefaultHandler($action);
         $handler->setNode($this);
         $handler->setPostvars($this->m_postvars);
         $handler->setAction($action);
         //If we use a default handler we need to register it to this node
         //because we might call it a second time.
         Tools::atkdebug('self::getHandler: Register default ActionHandler for ' . $this->m_type . " action: '" . $action . "'");
         $atk->atkRegisterNodeHandler($this->m_type, $action, $handler);
     }
     return $handler;
 }
Ejemplo n.º 11
0
 /**
  * Regenerates a user password and sends it to his e-mail address.
  *
  * @param string $username User for which the password should be regenerated
  *
  * @return bool
  */
 public function mailPassword($username)
 {
     $atk = Atk::getInstance();
     // Query the database for user records having the given username and return if not found
     $userNode = $atk->atkGetNode(Config::getGlobal('auth_usernode'));
     $selector = sprintf("%s.%s = '%s'", Config::getGlobal('auth_usertable'), Config::getGlobal('auth_userfield'), $username);
     $userrecords = $userNode->select($selector)->includes(array(Config::getGlobal('auth_userpk'), Config::getGlobal('auth_emailfield'), Config::getGlobal('auth_passwordfield')))->mode('edit')->getAllRows();
     if (count($userrecords) != 1) {
         Tools::atkdebug("User '{$username}' not found.");
         return false;
     }
     // Retrieve the email address
     $email = $userrecords[0][Config::getGlobal('auth_emailfield')];
     if (empty($email)) {
         Tools::atkdebug("Email address for '{$username}' not available.");
         return false;
     }
     // Regenerate the password
     $passwordAttr = $userNode->getAttribute(Config::getGlobal('auth_passwordfield'));
     $newPassword = $passwordAttr->generatePassword();
     // Update the record in the database
     $userrecords[0][Config::getGlobal('auth_passwordfield')]['hash'] = password_hash($newPassword, PASSWORD_DEFAULT);
     $userNode->updateDb($userrecords[0], true, '', array(Config::getGlobal('auth_passwordfield')));
     $db = $userNode->getDb();
     $db->commit();
     // Send an email containing the new password to user
     $subject = Tools::atktext('auth_passwordmail_subjectnew_password', 'atk');
     $body = Tools::atktext('auth_passwordmail_explanation', 'atk') . "\n\n";
     $body .= Tools::atktext(Config::getGlobal('auth_userfield')) . ': ' . $username . "\n";
     $body .= Tools::atktext(Config::getGlobal('auth_passwordfield')) . ': ' . $newPassword . "\n";
     //TODO: replace with some mailer object
     mail($email, $subject, $body);
     // Return true
     return true;
 }
Ejemplo n.º 12
0
 /**
  * Return the title to render.
  *
  * @param string $module the module in which to look
  * @param string $nodetype the nodetype of the action
  * @param string $action the action that we are trying to find a title for
  * @param bool $actiononly wether or not to return a name of the node
  *                           if we couldn't find a specific title
  *
  * @return string the title for the action
  */
 public function title($module, $nodetype, $action = null, $actiononly = false)
 {
     if ($module == null || $nodetype == null) {
         return '';
     }
     $atk = Atk::getInstance();
     return $this->nodeTitle($atk->atkGetNode($module . '.' . $nodetype), $action, $actiononly);
 }
Ejemplo n.º 13
0
 /**
  * Retrieve all possible module/node actions.
  *
  * @param array $record The record
  * @param bool $splitPerSection
  *
  * @return array Array with actions
  */
 public function getAllActions($record, $splitPerSection = false)
 {
     $atk = Atk::getInstance();
     $result = [];
     // hierarchic groups, only return actions of parent (if this record has a parent)
     $parentAttr = $this->m_parentAttrName;
     if (!empty($parentAttr) && is_numeric($record[$parentAttr])) {
         $db = $this->getDb();
         $query = 'SELECT DISTINCT node, action FROM ' . Config::getGlobal('auth_accesstable') . ' ' . 'WHERE ' . $this->m_accessField . ' = ' . $record[$parentAttr];
         $rows = $db->getRows($query);
         foreach ($rows as $row) {
             $module = Tools::getNodeModule($row['node']);
             $node = Tools::getNodeType($row['node']);
             $result[$module][$module][$node][] = $row['action'];
         }
     } else {
         // get nodes for each module
         foreach (array_keys($atk->g_modules) as $module) {
             $instance = $atk->atkGetModule($module);
             if (method_exists($instance, 'getNodes')) {
                 $instance->getNodes();
             }
         }
         // retrieve all actions after we registered all actions
         $result = $atk->g_nodes;
     }
     if (!$splitPerSection) {
         $temp = [];
         foreach ($result as $section => $modules) {
             foreach ($modules as $module => $nodes) {
                 if (!is_array($temp[$module])) {
                     $temp[$module] = [];
                 }
                 $temp[$module] = array_merge($temp[$module], $nodes);
             }
         }
         $result = $temp;
     }
     return $result;
 }
Ejemplo n.º 14
0
 /**
  * Creates an instance of the node we are searching on and stores it
  * in a member variable ($this->m_searchnodeInstance).
  *
  * @return bool
  */
 public function createSearchNodeInstance()
 {
     if (!is_object($this->m_searchnodeInstance)) {
         $atk = Atk::getInstance();
         $this->m_searchnodeInstance = $atk->atkGetNode($this->m_searchnode);
         return is_object($this->m_searchnodeInstance);
     }
     return true;
 }
Ejemplo n.º 15
0
 /**
  * Method for getting the relative path to the languagedirectory
  * of a module.
  * Supports 2 special modules:
  * - atk (returns the path of the atk languagedir)
  * - langoverrides (returns the path of the languageoverrides dir).
  *
  * Special method in that it can run both in static and non-static
  * mode.
  *
  * @param string $moduleName The module to get the languagedir for
  *
  * @return string The relative path to the languagedir
  */
 public function getLanguageDirForModule($moduleName)
 {
     if ($moduleName == 'atk') {
         $path = __DIR__ . '/../Resources/' . $this->LANGDIR;
     } else {
         if ($moduleName == 'langoverrides') {
             $path = Config::getGlobal('language_basedir', $this->LANGDIR);
         } else {
             $atk = Atk::getInstance();
             $path = $atk->moduleDir($moduleName) . $this->LANGDIR;
         }
     }
     return $path;
 }