/** @return $lastLogin Timestamp Updates the lastLogin field of a User to the current time. */ public function updateLastLogin() { $userId = $this->getUserId(); $db = Config::getDB(); //Updating timestamp: $stmt = $db->prepare('UPDATE users SET lastLogin=CURRENT_TIMESTAMP WHERE userId = ?'); $stmt->bind_param('i', $userId); $stmt->execute(); $stmt->close(); //Fetching timestamp: $stmt = $db->prepare('SELECT lastLogin FROM users WHERE userId = ?'); $stmt->bind_param('i', $userId); $stmt->execute(); $stmt->bind_result($lastLogin); $stmt->fetch(); $this->row['lastLogin'] = $lastLogin; $stmt->close(); return $lastLogin; }
/** @param $scanRectangleMap [scanUrn => [rectangle]] @param $user User, see auth/user.php @param $type int, see AreaOfInterestType @param $typeText String || null, see AreaOfInterestType @return $aoi AreaOfInterest || Exception Tries to create a new AreaOfInterest. Constraints: $scanUrn keys of $scanRectangleMap must be valid URNs for scans table. $scanRectangleMap must pass AreaOfInterestUrn::createUrn(). $type must pass AreaOfInterestType::validType(). $typeText may only be !== null, if AreaOfInterestType::hasText($type). Created urn may only have maximum length of 250. */ public static function createAOI($scanRectangleMap, $user, $type, $typeText = null) { $fail = function ($reason) { //Fail helper return new Exception("Problem in AreaOfInterest::createAOI(…). Reason: {$reason}"); }; //Checking some constraints: if (!is_array($scanRectangleMap)) { return $fail('$scanRectangleMap must be an array.'); } if (!$user instanceof User) { return $fail('$user must be instance of auth/user.php.'); } if (!AreaOfInterestType::validType($type)) { return $fail('$type has invalid/unexpected value.'); } if ($typeText !== null) { if (is_string($typeText)) { if (!AreaOfInterestType::hasText($type)) { return $fail('$typeText given when it was not allowed.'); } else { //Storing empty string in db instead of null: $typeText = ''; } } else { return $fail('Invalid value for $typeText: ' . $typeText); } } //Checking scan URNs: $scanUrns = array_keys($scanRectangleMap); if (!OmekaFile::validateUrns($scanUrns)) { return $fail('At least one urn was invalid. $urns: ' . json_encode($scanUrns)); } //Trying to create URN: $urn = AreaOfInterestUrn::createUrn($scanRectangleMap); if ($urn instanceof Exception) { $msg = $urn->getMessage(); return $fail('Could not create URN. ' . $msg); } if (strlen($urn) > 250) { return $fail("\$urn is longer than 250 chars: '{$urn}'."); } //Input valid, can create AreaOfInterest: $q = 'INSERT INTO areasOfInterest (urn,userId,typeEnum,typeText) VALUES (?,?,?,?)'; $stmt = Config::getDB()->prepare($q); $stmt->bind_param('siis', $urn, $user->getUserId(), $type, $typeText); $stmt->execute(); $stmt->close(); //Creating entries for scanAoiMap: $q = 'INSERT INTO scanAoiMap (aoiUrn, scanUrn) VALUES (?,?)'; foreach ($scanUrns as $scanUrn) { $stmt = Config::getDB()->prepare($q); $stmt->bind_param('ss', $urn, $scanUrn); $stmt->execute(); $stmt->close; } //Return AOI, iff possible: return self::getAOIFromUrn($urn); }
function AddDocument($sFile, $aPages, $objDM) { // We need a UNIQUE name and directory for this file $sDir = strftime("%F/"); $sDest = strftime("%H.%M.%S_document"); // Create directory (if not already there) if (!is_dir(Config::GetPath("dest") . $sDir)) { if (!mkdir(Config::GetPath("dest") . $sDir, Config::GetPermission("dirmask"), false)) { printf("Failed to create directory \"%s\"\n", Config::GetPath("dest") . $sDir); return FALSE; } else { // Adjust the rights $iOld = error_reporting(E_ERROR); chmod(Config::GetPath("dest") . $sDir, Config::GetPermission("dirmask")); chgrp(Config::GetPath("dest") . $sDir, Config::GetPermission("group")); chown(Config::GetPath("dest") . $sDir, Config::GetPermission("user")); error_reporting($iOld); } } // Make sure we don't collide with existing filename // TODO: NOT THREAD SAFE! $i = 1; while (file_exists(Config::GetPath("dest") . $sDir . $sDest . $i . ".pdf")) { $i++; } // Final destination is... $sDest = Config::GetPath("dest") . $sDir . $sDest . $i . ".pdf"; // Time to talk to mysql about this whole thing :) $db = mysql_pconnect(Config::getDB("host"), Config::getDB("username"), Config::getDB("password")); if (!$db) { printf("Cannot connect to database\n"); return FALSE; } if (!mysql_select_db(Config::getDB("database"), $db)) { printf("Cannot open scanner database\n"); return FALSE; } // Time to move the file AND add that into the database if (!rename($sFile, $sDest)) { printf("Couldn't move \"%s\" into \"%s\"!\n", $sFile, $sDest); return FALSE; } // Adjust the rights $iOld = error_reporting(E_ERROR); chmod($sDest, Config::GetPermission("filemask")); chgrp($sDest, Config::GetPermission("group")); chown($sDest, Config::GetPermission("user")); error_reporting($iOld); $SQL = sprintf("INSERT INTO documents (filename) VALUES ('%s')", $sDest); if (mysql_query($SQL, $db) === FALSE) { printf("Unable to add document to database: %s\n", mysql_error($db)); return FALSE; } $iID = mysql_insert_id($db); // Finally, using the ID from the document, we add ALL the pages to it $sAllData = ""; $sSplitter = uniqid(Config::GetSplitter(), true); $iPages = 0; foreach ($aPages as $iPage) { $sFile = sprintf("page%03d.txt", $iPage); $sContent = file_get_contents(Config::GetPath("tmp") . $sFile); if ($sContent !== FALSE) { $sAllData .= strtolower($sContent) . $sSplitter; // Space to avoid run-in $iPages++; } else { printf("Unable to load contents of \"%s\" into memory\n", Config::GetPath("tmp") . $sFile); return FALSE; } } // Save this data $SQL = sprintf("INSERT INTO rawtext VALUES (%d, '%s', '%s')", $iID, mysql_real_escape_string($sAllData), mysql_real_escape_string($sSplitter)); if (mysql_query($SQL, $db) === FALSE) { printf("Failed to insert data document %d: %s\n", $iID, mysql_error($db)); return FALSE; } // Also update pagecount $SQL = sprintf("UPDATE documents SET pagecount = %d WHERE id = %d", $iPages, $iID); if (mysql_query($SQL, $db) === FALSE) { printf("Failed to update pagecount for %d: %s\n", $iID, mysql_error($db)); return FALSE; } // Reformat the data $sAllData = str_replace($sSplitter, "\n", $sAllData); // Now for some magic, // we try and guess the original date of the data $iDate = $objDM->GuessOriginalDate($sAllData); if ($iDate !== FALSE && $iDate != 0) { $SQL = sprintf("UPDATE documents SET dated = FROM_UNIXTIME(%d) WHERE id = %d", $iDate, $iID); $res = mysql_query($SQL, $db); if ($res === FALSE) { printf("ERROR! Failed to update document date: %s\n", mysql_error($db)); return FALSE; } } // Finally, using the complete contents, we try and apply a category $res = mysql_query("SELECT * FROM categories", $db); if ($res === FALSE) { printf("WARNING: Was unable to get categories, defaults to unclassified\n"); return TRUE; } $aResult = array(); while (($aRes = mysql_fetch_array($res)) !== FALSE) { if (trim($aRes["keywords"]) == "") { continue; } $aWords = preg_split("/[\\s,]*\\\"([^\\\"]+)\\\"[\\s,]*|" . "[\\s,]*'([^']+)'[\\s,]*|" . "[\\s,]+/", $aRes["keywords"], 0, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE); // Count the occurance of the keywords in the document (case insensitive) $iHits = 0; foreach ($aWords as $sWord) { $bNegative = false; if ($sWord[0] == '-') { $bNegative = true; $sWord = substr($sWord, 1); } $iHit = substr_count($sAllData, $sWord); // If _ANY_ keyword fails, this isn't considered a hit at all if ($iHit > 0 == $bNegative) { $iHits = 0; break; } $iHits += $iHit; } if ($iHits != 0) { array_push($aResult, array("id" => $aRes["id"], "hits" => $iHits)); } } if (!empty($aResult)) { //printf("%d categorie(s) matched\n", count($aResult)); //print_r($aResult); $iHighest = 0; $aChosen = FALSE; foreach ($aResult as $aEntry) { if ($aEntry["hits"] > $iHighest) { $iHighest = $aEntry["hits"]; $aChosen = $aEntry; } } //printf(" Category %d was chosen due to highest hits.\n", $aChosen["id"]); $SQL = sprintf("UPDATE documents SET category = %d WHERE id = %d", $aChosen["id"], $iID); $res = mysql_query($SQL, $db); if ($res === FALSE) { printf("ERROR! Failed to update document category: %s\n", mysql_error($db)); return FALSE; } } return TRUE; }
function __construct() { $this->config = Config::getInstance(); $this->db = $this->config->getDB(); }
/** @param $urn String @return $projection CompletionVotesProjection || Exception Tries to create a CompletionVotesProjection for a Transcription. */ public static function projectTranscription($urn) { //Fail helper: $fail = function ($reason) use($urn) { return new Exception("CompletionVotesProjection::projectTranscription({$urn}) ran into a problem: {$reason}"); }; //Checking $urn: $q = 'SELECT COUNT(*) FROM transcriptions WHERE urn = ?'; $stmt = Config::getDB()->prepare($q); $stmt->bind_param('s', $urn); if (!self::countIsOne($stmt)) { return $fail('$urn not in database.'); } //Building $projection: $projection = new CompletionVotesProjection(); $projection->table = 'transcriptionCompleteness'; $projection->urn = $urn; //Done: return $projection; }
/** @param $url String @return $item OmekaItem || null Tries to fetch an OmekaItem from the omekaItems table given its URL. */ public static function getItemFromDbByUrl($url) { $q = 'SELECT urn, omekaUrl, featured, public, dublinCoreJSON ' . 'FROM omekaItems WHERE omekaUrl = ?'; $stmt = Config::getDB()->prepare($q); $stmt->bind_param('s', $url); $item = self::itemsFromDbData($stmt); if (count($item) === 1) { return current($item); } return null; }
/** @param $urn [String] || String @return $valid Boolean If $urn is a String: returns true iff $urn is a valid URN in our database. If $urn is an Array: returns and of self::validateUrns() for all its values. Otherwise returns false. */ public static function validateUrns($urn) { if (is_string($urn)) { $q = 'SELECT COUNT(*) FROM scans WHERE urn = ?'; $stmt = Config::getDB()->prepare($q); $stmt->bind_param('s', $urn); $stmt->execute(); $stmt->bind_result($count); $result = false; if ($stmt->fetch()) { $result = $count === 1; } $stmt->close(); return $result; } if (is_array($urn)) { foreach ($urn as $u) { $valid = self::validateUrns($u); if (!$valid) { return false; } } return true; } return false; }