Exemple #1
0
 /**
  * Queries the database with the given sql query.
  * This currently passes the query straight through to
  * xf_db_query, but it will be modified in the future to
  * automatically filter out blobs (because normally we don't want to 
  * retrieve blob columns.
  */
 function query($sql, $db = null, $lang = null, $as_array = false, $enumerated = false)
 {
     $app =& Dataface_Application::getInstance();
     $refreshModTimes = false;
     if ($as_array and $isSelect = strpos(strtolower(trim($sql)), 'select ') === 0) {
         if ($results = $this->memcache_get($sql, $lang) or is_array($results)) {
             if (@$this->app->_conf['cache_queries_log']) {
                 $fp = fopen('/tmp/querylog.log', 'a');
                 fwrite($fp, "\n[" . date('Y-m-d H:i:s') . "] Cached: " . $sql);
                 fclose($fp);
             }
             $this->cache_hits++;
             return $results;
         } else {
             if (@$this->app->_conf['cache_queries_log']) {
                 $fp = fopen('/tmp/querylog.log', 'a');
                 fwrite($fp, "\n[" . date('Y-m-d H:i:s') . "] Failed cached: " . $sql);
                 fclose($fp);
             }
             $this->cache_fails++;
             $orig_sql = $sql;
             // save the original sql before it is translated
         }
     } else {
         if (@$app->_conf['cache_queries']) {
             $refreshModTimes = true;
         }
     }
     //$fp = fopen('/tmp/querylog.log', 'a');
     //fwrite($fp, "\n[".date('Y-m-d H:i:s')."] Uncached: ".$sql);
     //fclose($fp);
     $this->count++;
     if ($this->app->_conf['multilingual_content']) {
         if (@$app->_conf['debug_sql']) {
             error_log("Before translation: " . $sql);
         }
         $sql = $this->translate_query($sql, $lang);
         if (PEAR::isError($sql)) {
             return $sql;
         }
         if (@$app->_conf['debug_sql']) {
             if (is_array($sql)) {
                 foreach ($sql as $sqli) {
                     error_log("After translation: " . $sqli);
                 }
             } else {
                 error_log("After translation: " . $sql);
             }
         }
     }
     if (!isset($db)) {
         $db = $this->app->db();
     }
     $update_insert_id = true;
     if (is_array($sql)) {
         $loopctr = 0;
         foreach ($sql as $q) {
             if ($loopctr++ > 0 and xf_db_insert_id($db)) {
                 $this->_insert_id = xf_db_insert_id($db);
                 $update_insert_id = false;
                 $q = str_replace("'%%%%%__MYSQL_INSERT_ID__%%%%%'", xf_db_insert_id($db), $q);
             }
             if (defined('DATAFACE_DEBUG_DB') or @$app->_conf['debug_sql']) {
                 echo "Performing query: '{$q}' <br>";
             }
             $res = xf_db_query($q, $db);
         }
     } else {
         if (defined('DATAFACE_DEBUG_DB') or @$app->_conf['debug_sql']) {
             echo "Performing query: '{$sql}' <br>";
         }
         $this->db_hits++;
         $res = xf_db_query($sql, $db);
     }
     if ($update_insert_id) {
         $this->_insert_id = xf_db_insert_id($db);
     }
     if ($res and $refreshModTimes) {
         Dataface_Table::getTableModificationTimes(true);
     }
     if ($as_array and $isSelect) {
         if (!$res) {
             return $res;
         }
         // We want to return this as an array rather than a resource
         $out = array();
         while ($row = $enumerated ? xf_db_fetch_row($res) : xf_db_fetch_assoc($res)) {
             $out[] = $row;
         }
         $this->memcache_set($orig_sql, $lang, $out);
         @xf_db_free_result($res);
         return $out;
     }
     return $res;
 }
Exemple #2
0
 /**
  * Backs up a record to the history table. This will automatically happen
  * when using Dataface_IO::save() if the [history] section exists in the 
  * conf.ini file.
  *
  * @param Dataface_Record &$record The record that is being backed up.
  * @param string $comments  Comments about this version to be stored.
  * @param string $lang The 2-digit language code of which language
  * 				 to use to back up this record.  If none is specified
  *				 then the current language of the system will be used.
  * @param integer $state Unused as yet.  Was intended to store state/workflow
  *				 information.. but ..
  * @returns integer The history id of the resulting history record.
  */
 function logRecord(&$record, $comments = '', $lang = null, $state = null)
 {
     $app =& Dataface_Application::getInstance();
     if (!isset($lang)) {
         $lang = $app->_conf['lang'];
     }
     if (!isset($state)) {
         $state = 0;
     }
     $fieldnames = array_keys($record->_table->fields());
     $sql = 'select `' . implode('`,`', $fieldnames) . '` from `' . $record->_table->tablename . '` where';
     $keynames = array_keys($record->_table->keys());
     $where_clauses = array();
     foreach ($keynames as $keyname) {
         $where_clauses[] = '`' . $keyname . '`=\'' . addslashes($record->strval($keyname)) . '\'';
     }
     $sql .= ' ' . implode(' and ', $where_clauses);
     if (@$app->_conf['multilingual_content']) {
         $db =& Dataface_DB::getInstance();
         $sql = $db->translate_query($sql, $lang);
         $sql = $sql[0];
     }
     $auth =& Dataface_AuthenticationTool::getInstance();
     $userRecord =& $auth->getLoggedInUser();
     if (!isset($userRecord)) {
         $user = null;
     } else {
         $user = $auth->getLoggedInUsername();
     }
     $insertsql = "insert into `" . $this->logTableName($record->_table->tablename) . "` \n\t\t\t(`" . implode('`,`', $fieldnames) . "`, `history__language`,`history__comments`,`history__user`,`history__state`,`history__modified`) \n\t\t\tselect *, '" . addslashes($lang) . "','" . addslashes($comments) . "','" . addslashes($user) . "','" . addslashes($state) . "', NOW() \n\t\t\tfrom (" . $sql . ") as t";
     $res = xf_db_query($insertsql, $app->db());
     if (!$res) {
         $this->updateHistoryTable($record->_table->tablename);
         $res = xf_db_query($insertsql, $app->db());
     }
     if (!$res) {
         echo $insertsql;
         trigger_error(xf_db_error($app->db()), E_USER_ERROR);
     }
     // Now for the individual fields
     $hid = xf_db_insert_id($app->db());
     foreach ($fieldnames as $fieldname) {
         $this->logField($record, $fieldname, $hid);
     }
     return $hid;
 }
Exemple #3
0
    /**
     * Sends the reset email to a particular user.
     * 
     * @param Dataface_Record $user The user record.
     * @return true on success
     *
     * @throws Exception code:  self::$EX_NO_USERNAME_FOR_USER If username is blank
     * @throws Exception code: self::$EX_NO_EMAIL_COLUMN_FOUND No email column was found in the users table.
     * @throws Exception code: self::$EX_NO_USERS_FOUND_WITH_EMAIL If the user record doesn't have an email address.
     */
    public function send_reset_email_for_user(Dataface_Record $user)
    {
        $app = Dataface_Application::getInstance();
        $auth = Dataface_AuthenticationTool::getInstance();
        $emailCol = $auth->getEmailColumn();
        $usernameCol = $auth->usernameColumn;
        if (!$emailCol) {
            throw new Exception(df_translate('actions.forgot_password.no_email_column_found', "No Email Column found in the users table.  Please specify one using the email_column directive in the [_auth] section of the conf.ini file."), self::$EX_NO_EMAIL_COLUMN_FOUND);
        }
        if (!$usernameCol) {
            throw new Exception(df_translate('actions.forgot_password.no_username_column_found', "No username column found in the users table. Please specify one using the username_column directive in the [_auth] section of the conf.ini file."), self::$EX_NO_USERNAME_COLUMN_FOUND);
        }
        if (!$user) {
            throw new Exception(df_translate('actions.forgot_password.null_user', "Cannot send email for null user"), self::$EX_NO_USERS_FOUND_WITH_EMAIL);
        }
        $username = $user->val($usernameCol);
        if (!$username) {
            throw new Exception(df_translate('actions.forgot_password.user_without_name', "Cannot reset password for user without a username"), self::$EX_NO_USERNAME_FOR_USER);
        }
        $email = $user->val($emailCol);
        if (!$email) {
            throw new Exception(df_translate('actions.forgot_password.user_without_email', "User has not email address on file"), $EX_NO_EMAIL_FOR_USER);
        }
        $ip = null;
        $val = ip2long($_SERVER['REMOTE_ADDR']);
        if ($val !== false) {
            $ip = sprintf('%u', $val);
        } else {
            $ip = 0;
            //If IP is empty MySQL throws Incorrect Integer value on insert
        }
        $expire_seconds = 600;
        if (@$app->_conf['reset_password_expiry']) {
            $expire_seconds = intval($app->_conf['reset_password_expiry']);
        }
        // Insert the entry
        $this->create_reset_password_table();
        $table = self::$TABLE_RESET_PASSWORD;
        $sql = "insert into `{$table}`\n\t\t\t(`request_uuid`, `username`, `request_ip`, `date_created`, `expires`)\n\t\t\tvalues\n\t\t\t(UUID(),'" . addslashes($username) . "','" . addslashes($ip) . "', NOW(), " . (time() + $expire_seconds) . ")";
        $res = xf_db_query($sql, df_db());
        if (!$res) {
            throw new Exception(xf_db_error(df_db()));
        }
        $id = xf_db_insert_id(df_db());
        $res = xf_db_query("select * from `{$table}` where request_id='" . addslashes($id) . "'", df_db());
        if (!$res) {
            throw new Exception(xf_db_error(df_db()));
        }
        $row = xf_db_fetch_assoc($res);
        if (!$row) {
            throw new Exception(df_translate('actions.forgot_password.failed_fetch_password_row', "Failed to fetch reset password request row from database after it has been inserted.  This should never happen ... must be a bug"));
        }
        $uuid = $row['request_uuid'];
        if (!$uuid) {
            throw new Exception(df_translate('actions.forgot_password.blank_uuid_for_reset_request', "Blank uuid for the reset request.  This should never happen.  Must be a bug."));
        }
        $url = df_absolute_url(DATAFACE_SITE_HREF . '?-action=forgot_password&--uuid=' . $uuid);
        $site_url = df_absolute_url(DATAFACE_SITE_URL);
        $msg = df_translate('actions.forgot_password.reset_password_request_email_body', <<<END
You have requested to reset the password for the user '{$username}'.
Please go to the URL below in order to proceed with resetting your password:
<{$url}>

If you did not make this request, please disregard this email.
END
, array('username' => $username, 'url' => $url));
        $subject = df_translate('actions.forgot_password.password_reset', "Password Reset");
        $del = $app->getDelegate();
        $info = array();
        if (isset($del) and method_exists($del, 'getResetPasswordEmailInfo')) {
            $info = $del->getResetPasswordEmailInfo($user, $url);
        }
        if (isset($info['subject'])) {
            $subject = $info['subject'];
        }
        if (isset($info['message'])) {
            $msg = $info['message'];
        }
        $parameters = null;
        if (isset($info['parameters'])) {
            $parameters = $info['parameters'];
        }
        $site_title = $app->getSiteTitle();
        $support_email = $_SERVER['SERVER_ADMIN'];
        if (isset($app->_conf['admin_email'])) {
            $support_email = $app->_conf['admin_email'];
        }
        if (isset($app->_conf['support_email'])) {
            $support_email = $app->_conf['support_email'];
        }
        $from_email = $support_email;
        if (strpos($support_email, '>') === false) {
            $from_email = $site_title . ' <' . $support_email . '>';
        }
        $headers = 'From: ' . $from_email . "\r\nReply-to: " . $from_email . "\r\nContent-type: text/plain; charset=" . $app->_conf['oe'];
        if (isset($info['headers'])) {
            $headers = $info['headers'];
        }
        //echo "Subject: $subject \nEmail: $email \n$msg \nHeaders: $headers";exit;
        if (@$app->_conf['_mail']['func']) {
            $func = $app->_conf['_mail']['func'];
        } else {
            $func = 'mail';
        }
        $res = $func($email, $subject, $msg, $headers, $parameters);
        if (!$res) {
            throw new Exception(df_translate('actions.forgot_password.failed_send_activation', "Failed to send activation email.  Please try again later."), DATAFACE_E_ERROR);
        } else {
            //echo "Successfully sent mail to $email";exit;
            return true;
        }
    }
Exemple #4
0
 /**
  * Returns the next free id in a sequence
  *
  * @param string  $seq_name  name of the sequence
  * @param boolean $ondemand  when true, the seqence is automatically
  *                            created if it does not exist
  *
  * @return int  the next id number in the sequence.
  *               A DB_Error object on failure.
  *
  * @see DB_common::nextID(), DB_common::getSequenceName(),
  *      DB_mysql::createSequence(), DB_mysql::dropSequence()
  */
 function nextId($seq_name, $ondemand = true)
 {
     $seqname = $this->getSequenceName($seq_name);
     do {
         $repeat = 0;
         $this->pushErrorHandling(PEAR_ERROR_RETURN);
         $result = $this->query("UPDATE {$seqname} " . 'SET id=LAST_INSERT_ID(id+1)');
         $this->popErrorHandling();
         if ($result === DB_OK) {
             // COMMON CASE
             $id = @xf_db_insert_id($this->connection);
             if ($id != 0) {
                 return $id;
             }
             // EMPTY SEQ TABLE
             // Sequence table must be empty for some reason, so fill
             // it and return 1 and obtain a user-level lock
             $result = $this->getOne("SELECT GET_LOCK('{$seqname}_lock',10)");
             if (DB::isError($result)) {
                 return $this->raiseError($result);
             }
             if ($result == 0) {
                 // Failed to get the lock
                 return $this->mysqlRaiseError(DB_ERROR_NOT_LOCKED);
             }
             // add the default value
             $result = $this->query("REPLACE INTO {$seqname} (id) VALUES (0)");
             if (DB::isError($result)) {
                 return $this->raiseError($result);
             }
             // Release the lock
             $result = $this->getOne('SELECT RELEASE_LOCK(' . "'{$seqname}_lock')");
             if (DB::isError($result)) {
                 return $this->raiseError($result);
             }
             // We know what the result will be, so no need to try again
             return 1;
         } elseif ($ondemand && DB::isError($result) && $result->getCode() == DB_ERROR_NOSUCHTABLE) {
             // ONDEMAND TABLE CREATION
             $result = $this->createSequence($seq_name);
             if (DB::isError($result)) {
                 return $this->raiseError($result);
             } else {
                 $repeat = 1;
             }
         } elseif (DB::isError($result) && $result->getCode() == DB_ERROR_ALREADY_EXISTS) {
             // BACKWARDS COMPAT
             // see _BCsequence() comment
             $result = $this->_BCsequence($seqname);
             if (DB::isError($result)) {
                 return $this->raiseError($result);
             }
             $repeat = 1;
         }
     } while ($repeat);
     return $this->raiseError($result);
 }
Exemple #5
0
 public function getInsertId()
 {
     return xf_db_insert_id($this->db());
 }
Exemple #6
0
 function getTranslationId(&$record, $language)
 {
     $app = Dataface_Application::getInstance();
     $sql = "select `id` from `dataface__translations` where `record_id`='" . addslashes($this->getRecordId($record)) . "' and `table`='" . addslashes($record->_table->tablename) . "' and `language`='" . addslashes($language) . "' limit 1";
     $res = xf_db_query($sql, $app->db());
     if (!$res) {
         $this->updateTranslationsTable();
         $res = xf_db_query($sql, $app->db());
         if (!$res) {
             throw new Exception(xf_db_error($app->db()), E_USER_ERROR);
         }
     }
     if (xf_db_num_rows($res) === 0) {
         @xf_db_free_result($res);
         $sql = "insert into `dataface__translations` (`record_id`,`language`,`table`,`last_modified`) VALUES (\n\t\t\t\t\t'" . addslashes($this->getRecordId($record)) . "',\n\t\t\t\t\t'" . addslashes($language) . "',\n\t\t\t\t\t'" . addslashes($record->_table->tablename) . "',\n\t\t\t\t\tNOW()\n\t\t\t\t\t)";
         $res = xf_db_query($sql, $app->db());
         if (!$res) {
             $this->updateTranslationsTable();
             $res = xf_db_query($sql, $app->db());
             if (!$res) {
                 throw new Exception(xf_db_error($app->db()), E_USER_ERROR);
             }
         }
         $id = xf_db_insert_id($app->db());
     } else {
         list($id) = xf_db_fetch_row($res);
         @xf_db_free_result($res);
     }
     return $id;
 }
function post($token = null, $comment, $uploaded_image_path)
{
    $db = new Database(df_db());
    global $error_message;
    $user = get_user($token);
    if (!$user) {
        $error_message = "Not logged in";
        return false;
    }
    $filename = null;
    if (@$uploaded_image_path) {
        $imagesDir = 'uploads';
        @mkdir($imagesDir);
        $imagesDir = 'uploads/' . sha1($user);
        @mkdir($imagesDir);
        $filename = time() . basename($uploaded_image_path) . '.png';
        if (!move_uploaded_file($uploaded_image_path, $imagesDir . '/' . $filename)) {
            $error_message = "Failed to upload file";
            return false;
        }
    }
    try {
        $res = $db->insertObject("posts", (object) array('username' => $user, 'date_posted' => time(), 'photo' => $filename, 'comment' => $comment));
        return xf_db_insert_id(df_db());
    } catch (Exception $ex) {
        $error_message = $ex->getMessage();
        return false;
    }
}
 public function buildRecord(xatacard_layout_Schema $schema, Dataface_Record $rec)
 {
     //Now we populate the record
     $out = new xatacard_layout_Record();
     $out->setSchema($schema);
     $out->setDataSource($this);
     $recordCache = array();
     $recordCache[$rec->getId()] = $rec;
     $recordData = array('records' => array(), 'fields' => array());
     $recordIdToIndex = array();
     foreach ($schema->getFields() as $key => $value) {
         if (strpos($key, '/') !== false) {
             // this is a first class property of the record so we can just get it.
             $index = count($recordData['records']);
             $recordData['records'][$index] = array('id' => $rec->getId(), 'version' => $rec->getVersion());
             $recordIdToIndex[$rec->getId()] = $index;
             $recordData['fields'][$key] = $recordIdToIndex[$rec->getId()];
             $out->setValue($key, $rec->getValue($key));
         } else {
             // this is a related record's property that we need to get from the related
             // records.
             $path = explode('/', $key);
             $crec = $rec;
             // As we're going to be going through related records
             // we need to mark the current record we are dealing
             /// with
             $fieldName = array_pop($path);
             // A flag to indicate if we should break the outer loop
             // after the inner loop finishes
             $shouldSkip = false;
             foreach ($path as $part) {
                 $index = 0;
                 if (preg_match('/^(.*)\\[(\\d+\\)]$/', $part, $matches)) {
                     $index = intval($matches[2]);
                     $part = $matches[1];
                 }
                 $related = $crec->getRelatedRecord($part, $index);
                 if (PEAR::isError($related)) {
                     throw new Exception(sprintf("MySQL datasource failed to load record because there was an error retrieving a column from a related record.  The field '%s' could not be retrieved because the following error: %s", $key, $related->getMessage()));
                 }
                 if (!$related) {
                     // No related record could be found to satisfy this path.
                     // This doesn't constitute an error.  It just means that the
                     // value should be blank.
                     $out->setValue($key, null);
                     $shouldSkip = true;
                     break;
                 }
                 unset($crec);
                 if (@$this->recordCache[$related->getId()]) {
                     $crec = $this->recordCache[$related->getId()];
                 } else {
                     $crec = $related->toRecord();
                     $this->recordCache[$related->getId()] = $crec;
                     $index = count($recordData['records']);
                     $recordData['records'][$index] = array('id' => $crec->getId(), 'version' => $rec->getVersion());
                     $recordIdToIndex[$crec->getId()] = $index;
                 }
                 unset($related);
             }
             if ($shouldSkip) {
                 // Something occurred in the inner loop to
                 // complete this step so we should skip the rest
                 // of this stuff.
                 continue;
             }
             if (!$crec) {
                 // This should never happen
                 throw new Exception(sprintf("MySQL datasource failed to load record because there was an error retrieving a related record required for one of the fields.  The field '%s' could not be retrieved.", $key));
             }
             $recordData['fields'][$key] = $recordIdToIndex[$crec->getId()];
             $out->setValue($key, $crec->val($fieldName));
         }
     }
     $cacheKeys = array_keys($recordCache);
     sort($cacheKeys);
     $versionstring = array();
     foreach ($cacheKeys as $k) {
         $versionstring[] = $k . ':' . $recordCache[$k]->getVersion();
     }
     $versionstring = implode(' ', $versionstring);
     $versionhash = md5($versionstring);
     $res = $this->query(sprintf("select `id` from `%s` where \n\t\t\t\tschema_id=%d and \n\t\t\t\tbase_record_id_hash='%s' and \n\t\t\t\tversion_hash='%s' and\n\t\t\t\t`lang`='%s'", str_replace('`', '', self::$RECORDS_TABLE), intval($schema->getId()), addslashes(md5($rec->getId())), addslashes($versionhash), addslashes($rec->lang)));
     if (xf_db_num_rows($res) >= 0) {
         $row = xf_db_fetch_row($res);
         $out->setId($row[0]);
     } else {
         $res = $this->query(sprintf("insert into `%s` (schema_id, base_record_id_hash, base_record_id, version_hash, `lang`, `record_data`)\n\t\t\t\tvalues (\n\t\t\t\t\t%d, '%s', '%s', '%s', '%s'\n\t\t\t\t)", intval($schema->getId()), addslashes(md5($rec->getId())), addslashes($rec->getid()), addslashes($versionhash), addslashes($rec->lang), addslashes(json_encode($recordData))));
         $out->setId(xf_db_insert_id(df_db()));
     }
     $out->clearSnapshot();
     return $out;
 }