Example #1
0
    public function testCreateNote()
    {
        $data = Filter_Client::createNoteEncode("bible", 1, 2, 3, "summary", "line1\nline2", false);
        $standard = <<<EOD
bible
1
2
3
summary

line1
line2
EOD;
        $this->assertEquals($standard, $data);
        $data = Filter_Client::createNoteDecode($standard);
        $this->assertEquals("bible", $data["bible"]);
        $this->assertEquals(1, $data["book"]);
        $this->assertEquals(2, $data["chapter"]);
        $this->assertEquals(3, $data["verse"]);
        $this->assertEquals("summary", $data["summary"]);
        $this->assertEquals("", $data["raw"]);
        $contents = <<<EOD
line1
line2
EOD;
        $this->assertEquals($contents, $data["contents"]);
    }
Example #2
0
 public function tearDown()
 {
     $database_bibles = Database_Bibles::getInstance();
     $database_modifications = Database_Modifications::getInstance();
     Filter_Client::set(false);
     $database_bibles->deleteBible("phpunit");
     $database_modifications->truncateTeams();
     Filter_Rmdir::rmdir($this->temporary_folder);
 }
Example #3
0
 public function create()
 {
     // No user menu in client mode.
     if (Filter_Client::enabled()) {
         return "";
     }
     // Modify the menu based on user access level.
     $mainmenu = $this->accesscontrol($this->mainmenu());
     // To create CSS menu the HTML structure needs to be like this:
     //   <ul id="menu" class="menu">
     //     <li>
     //       Menu entry
     //         <li>Subitem</li>
     //       </ul>
     //     </li>
     //     <li>Another entry</li>
     //   </ul>
     $document = new DOMDocument("1.0", "UTF-8");
     $document->encoding = "UTF-8";
     $document->preserveWhiteSpace = false;
     $document->loadXML('<ul id="usermenu" class="menu"></ul>');
     $xpath = new DOMXpath($document);
     $nodes = $xpath->query("//ul");
     $mainul = $nodes->item(0);
     // Go through the main menu.
     foreach ($mainmenu as $mainitem) {
         // Build the main menu.
         $mainhref = $mainitem[0];
         $maintext = $mainitem[1];
         $mainli = $document->createElement("li");
         $attribute = $document->createAttribute("class");
         $mainli->appendChild($attribute);
         $attribute->value = "toggle";
         $mainul->appendChild($mainli);
         if ($mainhref == "") {
             $mainaspan = $document->createElement("span");
         } else {
             $mainaspan = $document->createElement("a");
             $attribute = $document->createAttribute("href");
             $mainaspan->appendChild($attribute);
             $attribute->value = $mainhref;
         }
         $mainli->appendChild($mainaspan);
         $mainaspan->nodeValue = $maintext;
         // Build the submenu.
         $submenu = $mainitem[2];
         if (!$submenu) {
             continue;
         }
         $this->submenu($document, $mainli, $submenu);
     }
     // Get the result.
     $document->formatOutput = true;
     $menu = $document->saveXML($mainul);
     return $menu;
 }
Example #4
0
 public static function client_demo_warning()
 {
     $warning = "";
     if (Filter_Client::enabled()) {
         $database_config_general = Database_Config_General::getInstance();
         $address = $database_config_general->getServerAddress();
         if ($address == self::demo_address()) {
             $warning = Locale_Translate::_("Warning:") . " " . Locale_Translate::_("The client is connected to a public demo server.") . " " . Locale_Translate::_("Everybody can modify the data on that server.") . " " . Locale_Translate::_("After send and receive your data will reflect the data on the server.");
         }
     }
     return $warning;
 }
Example #5
0
 public static function not_yet_ready()
 {
     // While setup is not yet complete, it is not yet ready.
     $path = dirname(__DIR__) . "../setup";
     if (file_exists($path)) {
         return true;
     }
     // When client mode is prepared, but not yet enabled, it is not yet ready.
     if (Filter_Client::prepared()) {
         if (!Filter_Client::enabled()) {
             return true;
         }
     }
     // Ready to run.
     return false;
 }
Example #6
0
 public static function write($bible, $user = "")
 {
     // Client: User has access to all Bibles.
     if (Filter_Client::enabled()) {
         return true;
     }
     if ($user == "") {
         $session_logic = Session_Logic::getInstance();
         $user = $session_logic->currentUser();
     }
     $database_users = Database_Users::getInstance();
     if (!$database_users->hasAccess2Bible($user, $bible)) {
         return false;
     }
     $readonly = $database_users->hasReadOnlyAccess2Bible($user, $bible);
     return !$readonly;
 }
Example #7
0
 public static function queuesync($control)
 {
     // Send / receive only works in Client mode.
     if (!Filter_Client::enabled()) {
         return;
     }
     // Deal with a numerical minute to find out whether it's time to automatically sync.
     if (is_numeric($control)) {
         $database_config_general = Database_Config_General::getInstance();
         $repeat = $database_config_general->getRepeatSendReceive();
         // Sync every hour.
         if ($repeat == 1) {
             $control = $control % 60;
             if ($control == 0) {
                 $control = true;
             }
         }
         // Sync every five minutes.
         if ($repeat == 2) {
             $control = $control % 5;
             if ($control == 0) {
                 $control = true;
             }
         }
     }
     // Send and receive: It is time now, or it is manual.
     if ($control === true) {
         // Only queue the sync tasks if none are running at the moment.
         if (SendReceive_Logic::syncqueued()) {
             $database_logs = Database_Logs::getInstance();
             $database_logs->log("Not scheduling sync tasks, because the previous ones have not yet finished");
         } else {
             Tasks_Logic::queue(Tasks_Logic::PHP, array(__DIR__ . "/sendnotes.php"));
             Tasks_Logic::queue(Tasks_Logic::PHP, array(__DIR__ . "/sendbibles.php"));
             Tasks_Logic::queue(Tasks_Logic::PHP, array(__DIR__ . "/sendsettings.php"));
             Tasks_Logic::queue(Tasks_Logic::PHP, array(__DIR__ . "/externalresources.php"));
             Tasks_Logic::queue(Tasks_Logic::PHP, array(__DIR__ . "/usfmresources.php"));
         }
     }
 }
Example #8
0
 public static function deleteBible($bible)
 {
     $database_bibles = Database_Bibles::getInstance();
     $database_modifications = Database_Modifications::getInstance();
     $database_bibleactions = Database_BibleActions::getInstance();
     // Record data of the Bible to be deleted prior to deletion.
     if (Filter_Client::enabled()) {
         // Client stores Bible actions.
         $books = $database_bibles->getBooks($bible);
         foreach ($books as $book) {
             $chapters = $database_bibles->getChapters($bible, $book);
             foreach ($chapters as $chapter) {
                 $usfm = $database_bibles->getChapter($bible, $book, $chapter);
                 $database_bibleactions->record($bible, $book, $chapter, $usfm);
             }
         }
     } else {
         // Server stores diff data.
         $database_modifications->storeTeamDiffBible($bible);
     }
     // Delete the Bible from the database.
     $database_bibles->deleteBible($bible);
 }
Example #9
0
function enable_client($username, $password, $level)
{
    // Enable client mode upon a successful connection.
    Filter_Client::set(true);
    // Remove all users from the database, and add the current one.
    remove_all_users();
    $database_users = Database_Users::getInstance();
    $database_users->addNewUser($username, $password, $level, "");
    // Clear all pending note actions and Bible actions and settings updates.
    $database_noteactions = Database_NoteActions::getInstance();
    $database_bibleactions = Database_BibleActions::getInstance();
    $database_config_user = Database_Config_User::getInstance();
    $session_logic = Session_Logic::getInstance();
    $database_noteactions->clear();
    $database_noteactions->create();
    $database_bibleactions->clear();
    $database_bibleactions->create();
    $session_logic->setUsername($username);
    $database_config_user->setUpdatedSettings(array());
    // Set it repeats sync every so often.
    $database_config_general = Database_Config_General::getInstance();
    $database_config_general->setRepeatSendReceive(2);
    // Schedule a sync operation straight-away.
    SendReceive_Logic::queuesync(true);
}
Example #10
0
}
if (isset($_GET['runsync'])) {
    if (SendReceive_Logic::syncqueued()) {
        $view->view->successnotes = Locale_Translate::_("Still sending and receiving from the last time.");
    } else {
        SendReceive_Logic::queuesync(true);
        $view->view->successnotes = Locale_Translate::_("Will send and receive.");
    }
}
$view->view->client = Filter_Client::enabled();
if (isset($_GET['repeatsync'])) {
    $repeatsync = $_GET['repeatsync'];
    if (!is_numeric($repeatsync)) {
        $repeatsync = 0;
    }
    if ($repeatsync < 0) {
        $repeatsync = 0;
    }
    if ($repeatsync > 2) {
        $repeatsync = 2;
    }
    $database_config_general->setRepeatSendReceive($repeatsync);
}
$view->view->repeatsync = $database_config_general->getRepeatSendReceive();
if ($database_config_general->getServerAddress() == "") {
    $view->view->errornotes = Locale_Translate::_("Collaboration has not been set up for the Bibles and Consultation Notes");
}
$view->view->clientmode = Filter_Client::enabled();
$view->view->demo = Filter_Demo::client_demo_warning();
$view->render("index.php");
Assets_Page::footer();
Example #11
0
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
require_once "../bootstrap/bootstrap.php";
// Security: The script runs from the cli SAPI only.
Filter_Cli::assert();
$database_logs = Database_Logs::getInstance();
$database_config_bible = Database_Config_Bible::getInstance();
$database_config_general = Database_Config_General::getInstance();
$database_bibles = Database_Bibles::getInstance();
$database_bibleactions = Database_BibleActions::getInstance();
$database_users = Database_Users::getInstance();
$database_books = Database_Books::getInstance();
$database_logs->log(Locale_Translate::_("Sending and receiving Bibles"), Filter_Roles::TRANSLATOR_LEVEL);
$response = Filter_Client::setup();
if ($response === false || $response < Filter_Roles::GUEST_LEVEL || $response > Filter_Roles::ADMIN_LEVEL) {
    $database_logs->log(Locale_Translate::_("Failure initializing sending and receiving Bibles"), Filter_Roles::TRANSLATOR_LEVEL);
    die;
}
$address = $database_config_general->getServerAddress();
$users = $database_users->getUsers();
$user = $users[0];
$hash = $database_users->getmd5($user);
$communication_errors = false;
// Go through the Bibles / books / chapters that have actions recorded for them.
$bibles = $database_bibleactions->getBibles();
foreach ($bibles as $bible) {
    $books = $database_bibleactions->getBooks($bible);
    foreach ($books as $book) {
        $chapters = $database_bibleactions->getChapters($bible, $book);
Example #12
0
 /**
  * This handles email to users.
  * $identifier: the note that is being handled.
  * $label: prefix to the subject line of the email.
  * $users: array of users to be mailed.
  * $postpone: whether to postpone sending the email till the evening.
  */
 private function emailUsers($identifier, $label, $users, $postpone)
 {
     // Databases.
     $database_notes = Database_Notes::getInstance();
     $database_config_user = Database_Config_User::getInstance();
     $database_users = Database_Users::getInstance();
     $database_mail = Database_Mail::getInstance();
     $database_config_general = Database_Config_General::getInstance();
     // Send mail to all users.
     $summary = $database_notes->getSummary($identifier);
     $passages = Filter_Books::passagesDisplayInline($database_notes->getPassages($identifier));
     $contents = $database_notes->getContents($identifier);
     // Include a link to the note on the site.
     $contents .= "<br>\n";
     $siteUrl = $database_config_general->getSiteURL();
     $link = "{$siteUrl}/notes/note.php?id={$identifier}";
     $contents .= "<p><a href=\"{$link}\">View or respond online</a></p>\n";
     $mailto = "mailto:" . $database_config_general->getSiteMailAddress() . "?subject=(CNID{$identifier})";
     $contents .= "<p><a href=\"{$mailto}\">Respond by email</a></p>\n";
     // Deal with possible postponing email.
     $timestamp = time();
     if ($postpone) {
         $postpone = strtotime("today +21 hours");
         if ($postpone > $timestamp) {
             $timestamp = $postpone;
         }
     }
     // Send (but not in client mode).
     foreach ($users as $user) {
         if (!Filter_Client::enabled()) {
             $database_mail->send($user, "{$label} | {$passages} | {$summary} | (CNID{$identifier})", $contents, $timestamp);
         }
     }
 }
Example #13
0
 function clientAccess()
 {
     // If client mode is prepared,
     // log in as the first username in the users database,
     // of as the admin in case no user have been set up yet.
     if (Filter_Client::prepared()) {
         $database_users = Database_Users::getInstance();
         $users = $database_users->getUsers();
         if (empty($users)) {
             $user = "******";
             $level = Filter_Roles::ADMIN_LEVEL;
         } else {
             $user = $users[0];
             $level = $database_users->getUserLevel($user);
         }
         $this->setUsername($user);
         $this->level = $level;
         $this->logged_in = true;
         return true;
     }
     return false;
 }
Example #14
0
 private function settingsmenu()
 {
     $menu = array("users" => array("manage/users", Locale_Translate::_("Users"), NULL), array("manage/indexing", Locale_Translate::_("Indexing"), NULL), array("administration/language", Locale_Translate::_("Language"), NULL), array("administration/timezone", Locale_Translate::_("Timezone"), NULL), "mail" => array("administration/mail", Locale_Translate::_("Mail"), NULL), array("styles/indext", Locale_Translate::_("Styles"), $this->stylessubmenu()), array("versification/index", Locale_Translate::_("Versifications"), NULL), array("mapping/index", Locale_Translate::_("Verse mappings"), NULL), "collaboration" => array("administration/collaboration", Locale_Translate::_("Collaboration"), NULL), "client" => array("administration/client", Locale_Translate::_("Client"), NULL), array("fonts/index", Locale_Translate::_("Fonts"), NULL));
     // If the installation is not prepared for Client mode, disable the menu.
     // But keep the menu item in an open installation.
     include "config/open.php";
     if (!$open_installation) {
         if (!Filter_Client::prepared()) {
             unset($menu["client"]);
         }
     }
     // If Client mode is enabled, disable certain menu entries.
     if (Filter_Client::enabled()) {
         unset($menu["mail"]);
         unset($menu["users"]);
         unset($menu["collaboration"]);
     }
     return $menu;
 }
Example #15
0
    }
}
// Identifier for this $bible.
$bibleID = $database_bibles->getID($bible);
// Create an email with the checking results for this $bible.
$emailBody = array();
$hits = $database_check->getHits();
foreach ($hits as $hit) {
    if ($hit['bible'] == $bibleID) {
        $passage = Filter_Books::passagesDisplayInline(array(array($hit['book'], $hit['chapter'], $hit['verse'])));
        $data = Filter_Html::sanitize($hit['data']);
        $result = "<p>{$passage} {$data}</p>";
        $emailBody[] = $result;
    }
}
// Send email to users with write access to the Bible and a subscription to the notification.
if (count($emailBody) > 0) {
    $subject = Locale_Translate::_("Bible Checks") . " " . $bible;
    $emailBody = implode("\n", $emailBody);
    $users = $database_users->getUsers();
    foreach ($users as $user) {
        if ($database_config_user->getUserBibleChecksNotification($user)) {
            if (Access_Bible::write($bible, $user)) {
                if (!Filter_Client::enabled()) {
                    $database_mail->send($user, $subject, $emailBody);
                }
            }
        }
    }
}
$database_logs->log("Check {$bible}: Complete", Filter_Roles::TRANSLATOR_LEVEL);
Example #16
0
chdir(__DIR__);
require_once "../bootstrap/bootstrap.php";
if (Filter_Cli::not_yet_ready()) {
    die;
}
// The script runs through the cli Server API only.
Filter_Cli::assert();
ignore_user_abort(true);
set_time_limit(0);
// CPU-intensive actions run at night.
// This keeps the site more responsive during the day.
$config_general = Database_Config_General::getInstance();
$database_logs = Database_Logs::getInstance();
$hour = date('G');
$minute = date('i');
$client = Filter_Client::enabled();
// At midnight, for five minutes, do nothing to allow time for external backup
// without corrupting the SQLite databases due to simultaneous access by
// Bibledit-Web and the backup program.
if ($hour == 0) {
    if ($minute <= 5) {
        die;
    }
}
// At the sixth minute after midnight, after the backup silence, and any hour after, rotate the logbook.
if ($minute == 6) {
    $directory = dirname(__DIR__) . "/journal";
    Tasks_Logic::queue(Tasks_Logic::PHP, array("{$directory}/rotate.php"));
}
// Every minute send out queued email, except in offline mode.
if (!$client) {
Example #17
0
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
require_once "../bootstrap/bootstrap.php";
// Security: Page only runs from the cli SAPI.
Filter_Cli::assert();
$database_logs = Database_Logs::getInstance();
$database_logs->log("Database maintenance running", Filter_Roles::ADMIN_LEVEL);
// Whether running in client mode.
$database_config_general = Database_Config_General::getInstance();
$client_mode = Filter_Client::enabled();
// While VACUUM or REINDEX on a SQLite database are running,
// querying the database then introduces errors like "database schema has changed".
// Therefore this type of maintenance should not be done automatically.
$database = Database_Users::getInstance();
$database->trim();
$database->optimize();
$database = Database_Mail::getInstance();
$database->trim();
$database->optimize();
$database = Database_Confirm::getInstance();
$database->trim();
$database->optimize();
// No need to optimize the following because it is hardly ever written to.
$database = Database_Books::getInstance();
$database = Database_Styles::getInstance();
Example #18
0
 private function __construct()
 {
     // Default encoding.
     mb_internal_encoding("UTF-8");
     // On shared hosting the temporal location may give read or write failures.
     // Set private temporal location for PHP.
     // Set private temporal location for SQLite.
     // http://stackoverflow.com/questions/10394517/setting-sqlite-temp-store-directory
     $tmpdir = realpath(__DIR__ . "/../tmp");
     putenv("TMPDIR={$tmpdir}");
     // Check whether to run the website setup script.
     // On Linux it is sufficient to check whether the "setup" folder exists.
     // But on Windows, this setup folder cannot be deleted, so it would exist always.
     // Therefore, to support Windows, it checks whether the index file in in the setup folder.
     if (file_exists("../setup/index.php")) {
         $setupfolder = realpath("../setup");
         $myfolder = realpath(".");
         if ($setupfolder != $myfolder) {
             include "../filter/url.php";
             Filter_Url::redirect("../setup/index.php");
             die;
         }
     }
     // Set the include path: Where to look for included files.
     $this->bibledit_root_folder = dirname(dirname(__FILE__));
     $include_path = get_include_path() . PATH_SEPARATOR . $this->bibledit_root_folder;
     set_include_path($include_path);
     ini_set('include_path', $include_path);
     // Autoloader.
     // Automatically include the file that contains the $class_name.
     // E.g. class Database_Bibles would require file database/bibles.php.
     // Thus the name of the class determines which file gets required.
     // The above implies that all classes translate to files and folders in lower case.
     // An exception is made for the Zend_* classes.
     function __autoload($class_name)
     {
         if (substr($class_name, 0, 4) != "Zend") {
             $class_name = strtolower($class_name);
         }
         $path = str_replace("_", "/", $class_name);
         require_once $path . ".php";
     }
     // Register the function.
     spl_autoload_register('__autoload');
     // Disable magic quotes.
     if (function_exists("get_magic_quotes_gpc") && get_magic_quotes_gpc()) {
         foreach ($_GET as $k => $v) {
             $_GET[$k] = stripslashes($v);
         }
         foreach ($_POST as $k => $v) {
             $_POST[$k] = stripslashes($v);
         }
         foreach ($_COOKIE as $k => $v) {
             $_COOKIE[$k] = stripslashes($v);
         }
     }
     // General configuration database.
     $database_config_general = Database_Config_General::getInstance();
     // The site's timezone.
     $timezone = $database_config_general->getTimezone();
     if ($timezone) {
         date_default_timezone_set($timezone);
     }
     // Client mode setup.
     // In case the client mode is prepared, but not enabled,
     // the bootstrap script forwards to the client mode setup page,
     // unless it is already going to that page.
     if (Filter_Client::prepared()) {
         if (!Filter_Client::enabled()) {
             @($uri = $_SERVER["REQUEST_URI"]);
             $path = parse_url($uri, PHP_URL_PATH);
             $folder = pathinfo($path, PATHINFO_DIRNAME);
             $folder = basename($folder);
             $page = pathinfo($path, PATHINFO_BASENAME);
             if ($folder != "setup") {
                 if ($page != "topbar.php") {
                     if ($page != "client.php") {
                         Filter_Url::redirect("../administration/client.php");
                         die;
                     }
                 }
             }
         }
     }
 }
Example #19
0
if (!$pass_ok) {
    $database_logs->log("Incorrect password {$password} for user {$username}", Filter_Roles::MANAGER_LEVEL);
}
$level_ok = $level == $database_users->getUserLevel($username);
if (!$level_ok) {
    $database_logs->log("Incorrect role {$level} for user {$username}", Filter_Roles::MANAGER_LEVEL);
}
if (!$user_ok || !$pass_ok || !$level_ok) {
    // Unauthorized.
    http_response_code(401);
    die;
}
$session_logic->setUsername($username);
if ($action == Notes_Logic::noteActionCreate) {
    // Create the note on the server.
    $data = Filter_Client::createNoteDecode($content);
    $bible = $data["bible"];
    $book = $data["book"];
    $chapter = $data["chapter"];
    $verse = $data["verse"];
    $summary = $data["summary"];
    $raw = $data["raw"];
    $contents = $data["contents"];
    $server_id = $notes_logic->createNote($bible, $book, $chapter, $verse, $summary, $contents, $raw);
    // Update the note identifier on the server to be same as the client.
    $database_notes->setIdentifier($server_id, $note);
    // Update search field.
    $database_notes->updateSearchFields($note);
    $database_logs->log("Client created note on server" . ": {$summary}", Filter_Roles::MANAGER_LEVEL);
    echo "The server created the note";
} else {