/** * Append action buttons to the end of this form * * @param bool|null $valid Whether the form was validated */ private function _addButtons($valid) { $buttons = $valid === false ? $this->buttons : TIP_FORM_BUTTON_CLOSE; $group = array(); if ($buttons & TIP_FORM_BUTTON_SUBMIT) { $group[] =& $this->_createElement('submit'); } if ($buttons & TIP_FORM_BUTTON_RESET) { $group[] =& $this->_createElement('reset'); } if ($buttons & TIP_FORM_BUTTON_OK) { $uri = TIP::modifyActionUri(null, null, null, array('process' => 1)); $group[] =& $this->_createElement('link', 'ok', array('href' => $uri)); } if ($buttons & TIP_FORM_BUTTON_DELETE && $this->action_id == TIP_FORM_ACTION_DELETE) { $uri = TIP::modifyActionUri(null, null, null, array('process' => 1)); $group[] =& $this->_createElement('link', 'delete', array('href' => $uri)); } if ($buttons & TIP_FORM_BUTTON_CANCEL) { $group[] =& $this->_createElement('link', 'cancel', array('href' => $this->referer)); } if ($buttons & TIP_FORM_BUTTON_CLOSE) { $group[] =& $this->_createElement('link', 'close', array('href' => $this->follower)); } if ($buttons & TIP_FORM_BUTTON_DELETE && $this->action_id != TIP_FORM_ACTION_DELETE) { $data =& $this->master->getProperty('data'); $primary_key = $data->getProperty('primary_key'); $uri = TIP::buildActionUri($this->id, 'delete', $this->_form->getElementValue($primary_key)); $group[] =& $this->_createElement('link', 'delete', array('href' => $uri)); } // Append the group of buttons to the form $this->_form->addElement('group', 'buttons', null, $group, ' ', false); }
/** * Remove all comments linked to a master row * * @param array &$row The subject row * @param array|null $old_row The old row or null on no old row * @return bool true on success or false on error */ public function _onMasterDelete(&$row, $old_row) { $data =& $this->getProperty('data'); $master_data =& $this->master->getProperty('data'); $primary_key = $master_data->getProperty('primary_key'); if (!isset($row[$primary_key])) { return false; } $filter = $data->filter($this->parent_field, $row[$primary_key]); return $data->deleteRows($filter); }
private function _render() { if (!empty($this->_tree)) { return true; } $filter = $this->master->getProperty('data')->order($this->date_field); if (is_null($view =& $this->master->startDataView($filter))) { return false; } $rows =& $view->getProperty('rows'); if (empty($rows)) { $this->_tree = array(); $this->master->endView(); return true; } $tree =& $this->_tree; foreach ($rows as $id => &$row) { $action = str_replace('-id-', $id, $this->action); $row['url'] = TIP::buildActionUriFromTag($action, (string) $this->master); $row['title'] = $this->_renderField($this->title_field, $row); // Suppose the date is in SQL format $date = $row[$this->date_field]; list($y, $m, $day) = sscanf($date, "%d-%d-%d"); // Compute the year $year = sprintf('%04d', $y); if (!array_key_exists($year, $tree)) { $tree[$year] = array('title' => $year, 'url' => TIP::modifyActionUri(null, null, null, array($this->id => $year)), 'sub' => array(), 'ITEMS' => 0); isset($this->count_field) && ($tree[$year]['COUNT'] = 0); } ++$tree[$year]['ITEMS']; isset($this->count_field) && ($tree[$year]['COUNT'] += $row[$this->count_field]); // Compute the month $months =& $tree[$year]['sub']; $month = strftime('%B', mktime(0, 0, 0, $m, $day, $year)); $month_id = $year . sprintf('%02d', $m); if (!array_key_exists($month_id, $months)) { $months[$month_id] = array('title' => $month, 'url' => TIP::modifyActionUri(null, null, null, array($this->id => $month_id)), 'sub' => array(), 'ITEMS' => 0); isset($this->count_field) && ($months[$month_id]['COUNT'] = 0); } ++$months[$month_id]['ITEMS']; isset($this->count_field) && ($months[$month_id]['COUNT'] += $row[$this->count_field]); $months[$month_id]['sub'][$id] =& $row; isset($this->count_field) && ($row['COUNT'] = $row[$this->count_field]); } return true; }
/** * Update the history on a master row deletion * * Updates the linked list by skipping the deleted history row * before deleting the row itsself. */ public function _onMasterDelete(&$row, $old_row) { $master_data =& $this->master->getProperty('data'); $id = $row[$master_data->getProperty('primary_key')]; $engine =& $this->data->getProperty('engine'); $query = $this->data->rowFilter($id); // Start the transaction here to avoid race conditions if (!$engine->startTransaction()) { // This error must be caught here to avoid the rollback return false; } // Get the current version row if (!($view =& $this->startDataView($query))) { $engine->endTransaction(false); return false; } $current_row = $view->current(); $this->endView(); if (empty($current_row)) { // No history found: return operation done (just in case...) return $engine->endTransaction(true); } // Get the previous version row $query = $this->data->filter($this->next_field, $id); if (!($view =& $this->startDataView($query))) { $engine->endTransaction(false); TIP::warning("no row to delete ({$id})"); TIP::notifyError('notfound'); return false; } $previous_row = $view->current(); $this->endView(); // Perform the operations $done = $this->data->deleteRow($id); if ($done && is_array($previous_row)) { // Update the next_field of previous_row $new_previous_row = $previous_row; $new_previous_row[$this->next_field] = $current_row[$this->next_field]; $done = $this->data->updateRow($new_previous_row, $previous_row); } // Close the transaction $done = $engine->endTransaction($done) && $done; return $done; }
/** * Process an add action * * Overrides the default callback providing email notification * when requested. * * @param array &$row The subject row * @param array|null $old_row The old row or null on no old row * @return bool true on success, false on errors */ public function _onAdd(&$row, $old_row) { if (!parent::_onAdd($row, $old_row)) { return false; } if (empty($this->notify_to)) { // No notification required return true; } $eol = "\r\n"; $env = 'TiP-' . TIP_VERSION_BRANCH; $sys = 'PHP-' . phpversion(); $headers = 'From: ' . $this->_getServerEmail() . $eol; $headers .= 'X-Mailer: TIP_Request module ' . "({$env}; {$sys})" . $eol; $headers .= 'MIME-Version: 1.0' . $eol; $headers .= 'Content-Type: text/plain; charset=ISO-8859-1'; // Assign current_row, so getField() checks for values in this row $this->_current_row =& $row; ob_start(); if ($this->tryRun($this->message_template)) { $message = ob_get_clean(); } elseif (array_key_exists($this->message_template, $row)) { ob_end_clean(); $message = $row[$this->message_template]; } else { ob_end_clean(); $message = 'Undefined message'; } $message = wordwrap(utf8_decode($message), 66); if (!mail($this->notify_to, $this->subject_text, $message, $headers)) { TIP::warning("Unable to send an email message to {$this->notify_to}"); return false; } return true; }
/** * Constructor * * Initializes a TIP_Picasa2 instance. * * @param array $options Properties values */ protected function __construct($options) { parent::__construct($options); }
/** * 'on_row' callback for TIP_Data_View * * Adds the following calculated fields to every data row: * - 'TOTAL': the sum of all votes * - 'PERCENT1': percentual (rounded to integer) of 'votes1' * - 'PERCENT2': percentual (rounded to integer) of 'votes2' * - 'PERCENT3': percentual (rounded to integer) of 'votes3' * - 'PERCENT4': percentual (rounded to integer) of 'votes4' * - 'PERCENT5': percentual (rounded to integer) of 'votes5' * - 'PERCENT6': percentual (rounded to integer) of 'votes6' * * @param array &$row The row as generated by TIP_Data_View * @return bool always true */ public function _onDataRow(&$row) { $total = $row['votes1'] + $row['votes2'] + $row['votes3'] + $row['votes4'] + $row['votes5'] + $row['votes6']; $row['TOTAL'] = $total; // Avoid division per 0 $total > 0 || ($total = 1); $row['PERCENT1'] = round($row['votes1'] * 100 / $total); $row['PERCENT2'] = round($row['votes2'] * 100 / $total); $row['PERCENT3'] = round($row['votes3'] * 100 / $total); $row['PERCENT4'] = round($row['votes4'] * 100 / $total); $row['PERCENT5'] = round($row['votes5'] * 100 / $total); $row['PERCENT6'] = round($row['votes6'] * 100 / $total); // Chain-up the parent callback return parent::_onDataRow($row); }
/** * Constructor * * Initializes a TIP_Devhelp2 instance. * * @param array $options Properties values */ protected function __construct($options) { // By default, do not use a built-in template: if needed, // it must be explicitely set in the $options array $this->view_template = null; parent::__construct($options); }
/** * Get the data rows and return a renderer ready to be used * * Overrides the default method to customize the levels to be * returned by the renderer. * * @param string $action The action template string * @return HTML_Menu_TipRenderer|null The renderer or * null on errors */ protected function &_getRenderer($action) { if (!is_null($renderer = parent::_getRenderer($action))) { $renderer->setLevels($this->levels); } return $renderer; }
/** * Process an add action * * Overrides the default add callback setting 'count_field' and * 'counted_field' to the current sponsor count. * * @param array &$row The subject row * @param array|null $old_row The old row or null on no old row * @return bool true on success, false on errors */ public function _onAdd(&$row, $old_row) { if (isset($this->count_field)) { $row[$this->count_field] = $this->_row[$this->count_field]; } if (isset($this->counted_field)) { $row[$this->counted_field] = $this->_row[$this->count_field]; } return parent::_onAdd($row, $old_row); }
/** * Perform a browse action * * Overrides the "browse" action to substitute {terms} in the query URI. * * @param array &$conditions The browse conditions * @return bool true on success or false on errors */ protected function actionBrowse(&$conditions) { // Prepare the terms: append " site:thisdomain" to limit the query // to the current site $terms = TIP::getGetOrPost('terms', 'string'); $terms .= ' site:' . $_SERVER['SERVER_NAME']; $query =& $this->data->getProperty('path'); $query = str_replace('{terms}', urlencode($terms), $query); return parent::actionBrowse($conditions); }
/** * Process a delete action * * Overrides the default delete action erasing both master and child rows. */ public function _onDelete(&$row, $old_row) { $child =& $this->_getChildModule(); if (is_null($child)) { // No child module: chain-up the parent method return parent::_onDelete($row, $old_row); } elseif (!$child) { // An error occurred somewhere: do nothing return false; } $primary_key = $this->data->getProperty('primary_key'); if (!array_key_exists($primary_key, $row) || is_null($id = $row[$primary_key])) { TIP::warning("no primary key defined (field {$primary_key})"); return false; } $engine =& $this->data->getProperty('engine'); if (!$engine->startTransaction()) { // This error must be caught here to avoid the rollback return false; } $done = parent::_onDelete($row, $old_row) && $child->getProperty('data')->deleteRow($id); $done = $engine->endTransaction($done) && $done; return $done; }
/** * Update the cookie on password changed * * @param array &$row The subject row * @param array $old_row The old row * @return bool true on success, false on errors */ public function _onEdit(&$row, $old_row = null) { // Ensure $old_row is properly populated is_array($old_row) || ($old_row =& $this->_old_row); if (!is_array($old_row) || !parent::_onEdit($row, $old_row)) { return false; } // Update the internal data $this->_row = $row; $this->_old_row = $row; // The cookie must be updated on password change if (array_key_exists('password', $row) && array_key_exists('password', $old_row) && strcmp($row['password'], $old_row['password']) != 0) { $this->_updateCookie(); } return true; }
/** * 'on_row' callback for TIP_Data_View * * Adds the following calculated fields to every data row: * - 'MESSAGE': a reference to the proper localized message * * @param array &$row The row as generated by TIP_Data_View * @return bool always true */ public function _onDataRow(&$row) { $row['MESSAGE'] = $row[$this->locale]; // Chain-up the parent callback return parent::_onDataRow($row); }
protected function runTrustedAction($action) { switch ($action) { case 'flag': return !is_null($id = $this->fromGetOrPost()) && $this->isNotOwner($id) && $this->actionFlag($id); case 'refresh': return !is_null($id = $this->fromGetOrPost()) && $this->isOwner($id) && $this->actionRefresh($id); } return parent::runTrustedAction($action); }