Kontakt - Datenschutz

Subversion

<?php
/**
 * Links controller
 *
 * @category  YD
 * @package   Web
 * @author    Sven Drieling <sd@sven-drieling.de>
 * @copyright 2013-2014 Sven Drieling
 * @license   http://opensource.org/licenses/mit-license.php MIT license
 * @version   0.1.0alpha1
 */

namespace YD\Web;

require_once __DIR__ . '/helperFunctions.php';
require_once __DIR__ . '/Link.php';

use YD\Web\Links as helper;



class Links {
    private $dbh           = null;

    private $sthInsertLink = null;
    private $sthUpdateLink = null;
    private $sthDeleteLink = null;
    private $sthReadByID   = null;

    private $sqlInsertLink = <<< SQL
INSERT INTO links (created, title, uri, description) VALUES (:created, :title, :uri, :description)
SQL;

    private $sqlUpdateLink = <<< SQL
UPDATE links SET title = :title, uri = :uri, description = :description WHERE id = :id
SQL;

    private $sqlReadByID = <<< SQL
SELECT id, created, title, uri, description FROM links WHERE id = :id
SQL;

    private $sqlDeleteLink = <<< SQL
DELETE FROM links WHERE id = :id
SQL;

    private $sqlSearch = <<< SQL
SELECT id, created, title, uri, description FROM links WHERE title ILIKE :search OR description ILIKE :search
SQL;


    public $templates = [];

    public $viewIndex = null;
    public $view      = null;


    public function __construct() {
        $cfg = $GLOBALS['linksConfig'];

        $this->dbh = new \PDO("pgsql:dbname={$cfg['dbName']};host={$cfg['dbHost']}", $cfg['dbUsername'], $cfg['dbPassword']);
        $this->dbh->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
    }


    public function showIndex($view = null) {
        $result = '';
        $view   = is_null($view) ? $this->viewIndex : $view;

        $result .= "<form action='index.html' method='post'>\n";

        $query = 'SELECT id, created, title, uri, description FROM links ORDER BY created DESC';
        foreach($this->dbh->query($query) as $l) {
            $link = new \YD\Web\Links\Link($l);

            if(!is_null($view)) {
                $result .= $view($link);
            } else {
                $result .= $link->title . "\n";
                $result .= \substr($link->description, 0, 80) . "\n";
            }
        }

        $result .= "</form>\n";


        return $result;
    }


    public function showLastX($last, $view = null) {
        $result = '';
        $view   = is_null($view) ? $this->view : $view;


        $query = "SELECT id, created, title, uri, description FROM links ORDER BY created DESC LIMIT {$last}";
        foreach($this->dbh->query($query) as $l) {
            $link = new \YD\Web\Links\Link($l);

            if(!is_null($view)) {
                $result .= $view($link);
            } else {
                $result .= $link->title . "\n";
                $result .= \substr($link->description, 0, 80) . "\n";
            }
        }


        return $result;
    }


    public function saveOverviewAsHTML32() {
        $filenameOverviewNew = __DIR__ . '/bookmarksOverview_new.html';
        $filenameOverview    = __DIR__ . '/bookmarksOverview.html';


        $query = "SELECT id, created, title, uri, description FROM links ORDER BY created DESC LIMIT 6";
        $result = $this->dbh->query($query);
        if(false === $result) {
            throw new \Exception('Get overview failed.');
        }

        $links = $result->fetchAll();
        if(false === $result) {
            throw new \Exception('Get overview failed.');
        }

        $file = fopen($filenameOverviewNew, 'w');
        if(false === $file) {
            throw new \Exception('Open overview file failed.');
        }

        for($i = 0; $i < 3; $i++) {
            fputs($file, "<tr>\n");

            fputs($file, "<td width='50%' valign='top'>\n");
            if(isset($links[$i])) {
                $link    = new \YD\Web\Links\Link($links[$i]);
                $date    = new \DateTime($link->created, new \DateTimeZone('UTC'));
                $created = $date->format('d-M-Y');

                $title       = Links\htmlUTF8ToLatin1($link->title);
                $description = Links\htmlUTF8ToLatin1($link->description);

                //fputs($file, "<b><font color='#000000'>{$created}: <a href='{$link->uri}'>{$title}, {date}, {source}</a></font></b>\n");
                fputs($file, "<b><font color='#000000'>{$created}: <a href='{$link->uri}'>{$title}</a></font></b>\n");
                fputs($file, "{$description}\n");
            }
            fputs($file, "</td>\n");

            fputs($file, "<td>&nbsp;</td>\n");

            fputs($file, "<td width='50%' valign='top'>\n");
            if(isset($links[$i + 3])) {
                $link    = new \YD\Web\Links\Link($links[$i + 3]);
                $date    = new \DateTime($link->created, new \DateTimeZone('UTC'));
                $created = $date->format('d-M-Y');

                $title       = Links\htmlUTF8ToLatin1($link->title);
                $description = Links\htmlUTF8ToLatin1($link->description);

                //fputs($file, "<b><font color='#000000'>{$created}: <a href='{$link->uri}'>{$title}, {date}, {source}</a></font></b>\n");
                fputs($file, "<b><font color='#000000'>{$created}: <a href='{$link->uri}'>{$title}</a></font></b>\n");
                fputs($file, "{$description}\n");
            }
            fputs($file, "</td>\n");

            fputs($file, "</tr>\n");
        }

        fputs($file, "<tr><td colspan='3'>&nbsp;<p>=&gt; <a href='/bookmarks/'>Weitere Bookmarks</a></td></tr>\n");

        fclose($file);

        if(false === rename($filenameOverviewNew, $filenameOverview)) {
            throw new \Exception('Rename overviewNew to overview failed.');
        }


        return true;
    }


    public function readByID($id) {
        // TODO Check id
        $link = null;

        $this->sthReadByID = $this->dbh->prepare($this->sqlReadByID);

        $this->sthReadByID->execute([':id' => $id]);

        $result = $this->sthReadByID->fetch();
        if(false === $result) {
            throw new \Exception(__CLASS__ . ": Link with id '{$id}' does not exists.");
        } else {
            $link = new \YD\Web\Links\Link($result);
        }


        return $link;
    }


    public function getLastModified() {
        $query  = 'SELECT MAX(created) AS last_modified FROM links';
        $result = $this->dbh->query($query);

        if(false === $result) {
            throw new \Exception('getLastModified() failed.');
        }

        $row = $result->fetch();
        if(false === $row) {
            throw new \Exception('getLastModified() failed.');
        }


        return $row['last_modified'];
    }


    public function create(\YD\Web\Links\Link $link) {
        $this->sthInsertLink = $this->dbh->prepare($this->sqlInsertLink);

        try {
            $created = new \DateTime('now', new \DateTimeZone('UTC'));

            $this->sthInsertLink->execute([':created'     => $created->format('Y-m-d H:i:s'),
                                           ':title'       => $link->title,
                                           ':uri'         => $link->uri,
                                           ':description' => $link->description]);

            $GLOBALS['page']['message']['content'] = 'Link added.';


            return true;
        } catch (\PDOException $e) {
            // "SQLSTATE[23505]: Unique violation: 7 ERROR:  duplicate key value violates unique constraint
            if(23505 == $e->getCode()) {
                $GLOBALS['page']['message']['content'] = 'Link already exists.';
            } else {
                $GLOBALS['page']['message']['content'] = "ERROR: " . helper\e($e->getMessage());
            }


            return false;
        }
    }


    public function update(\YD\Web\Links\Link $link) {
        // TODO Check id?
        $this->sthUpdateLink = $this->dbh->prepare($this->sqlUpdateLink);

        $this->sthUpdateLink->execute([':title'       => $link->title,
                                       ':uri'         => $link->uri,
                                       ':description' => $link->description,

                                       ':id'          => $link->id]);
    }


    public function delete($id) {
        // TODO Check id?
        $this->sthDeleteLink = $this->dbh->prepare($this->sqlDeleteLink);

        try {
            $this->sthDeleteLink->execute([':id' => $id]);
            $GLOBALS['page']['message']['content'] = 'Link deleted.';


            return true;
        } catch (\PDOException $e) {
            $GLOBALS['page']['message']['content'] = "ERROR: " . helper\e($e->getMessage());


            return false;
        }
    }



    public function showNavigation() {
        $result = "<form id='form-navigation' action='index.html' method='post'>\n";

        if($this->isLogin()) {
            $result .= " <button name='_command'  value='showNewForm' type='submit'>Add link</button>";
            $result .= " <button name='_command'  value='updateOverview' type='submit'>Update overview</button>";
            $result .= " <button name='_command'  value='logout'      type='submit'>Logout</button>";
        } else {
            $result .= " <button name='_command'  value='showLoginForm' type='submit'>Login</button>";
        }

        $result .= "</form>";


        return $result;
    }


    public function showNewForm(\YD\Web\Links\Link $link = null) {
        if(is_null($link)) {
            $link = new \YD\Web\Links\Link();
        }

        $this->loadTemplates();

        $options = "<select name='templateName' size='1'>\n";
        foreach($this->templates as $templateName => $template) {
            $selected         = $_SESSION['templateName'] === $templateName ? " selected='selected'" : "";
            $templateNameHTML = helper\e($templateName);
            $options         .= "  <option value='{$templateNameHTML}'{$selected}>{$templateNameHTML}</option>\n";
        }
        $options .= "</select>\n";


        $templateNameSave = helper\e($_SESSION['templateName']);

        return <<< HTML
<form action='index.html' method='post'>
    <p>{$options} <button type='submit' name='_command' value='selectTemplate'>Select Template</button></p>

    <p>
    Title: <input type='text' name='title' value='{$link->§title}' size='80' maxlength='150' /><br />
    URI  : <input type='text' name='uri'   value='{$link->§uri}' size='80' maxlength='255' /><br />

    <textarea name='description' rows='20' cols='75'>{$link->§description}</textarea>
    </p>

    <p>
    <button type='submit' name='_command' value='show'   >Cancel</button>
    <button type='submit' name='_command' value='addLink'>Add Link</button>
    <button type='submit' name='_command' value='saveTemplate'>Save Template</button>
    <input  type='text'   name='templateNameSave' value='{$templateNameSave}' size='25' maxlength='30' />
</form>
HTML;
    }


    public function showEditForm(\YD\Web\Links\Link $link) {
        return <<< HTML
<form action='index.html' method='post'>
    Title: <input type='text' name='title' value='{$link->§title}' size='80' maxlength='150' /><br />
    URI  : <input type='text' name='uri'   value='{$link->§uri}'   size='80' maxlength='255' /><br />

    <textarea name='description' rows='20' cols='75'>{$link->§description}</textarea>

    <input type='hidden' name='id'   value='{$link->§id}' />

    <p>
    <button type='submit' name='_command' value='show'      >Cancel</button>
    <button type='submit' name='_command' value='updateLink'>Update Link</button>
</form>
HTML;
    }


    public function showLoginForm() {
        return <<< HTML
<form action='index.html' method='post'>
    Login:    <input type='text'     name='login'     value='' size='20' maxlength='20' /><br />
    Password: <input type='password' name='password'  value='' size='20' maxlength='255' /><br />

    <button type='submit' name='_command' value='show' >Cancel</button>
    <button type='submit' name='_command' value='login'>Login</button>
</form>
HTML;
    }


    public function login() {
        $cfg = $GLOBALS['linksConfig'];

        if($_POST['login'] === $cfg['loginUsername'] && $_POST['password'] === $cfg['loginPassword']) {
            $_SESSION['isLogin'] = true;
            $GLOBALS['page']['message']['content'] = 'Login successful';
        } else {
            $_SESSION['isLogin'] = false;
            $GLOBALS['page']['message']['content'] = 'Login failed';
        }


        return $this->isLogin();
    }


    public function logout() {
        $_SESSION['isLogin'] = false;
        $GLOBALS['page']['message']['content'] = 'Logout successful';
    }


    public function isLogin() {
        return $_SESSION['isLogin'];
    }


    public function isAdmin() {
        return $this->isLogin(); // TODO Implement
    }


    public function loadTemplates() {
        $cfg = $GLOBALS['linksConfig'];

        $this->templates = [];


        if(!file_exists($cfg['templatesFilename'])) {
            throw new \Exception("Templates file '{$cfg['templatesFilename']}' does not exists.");
        }

        $templatesJSON = \file_get_contents($cfg['templatesFilename']);
        if(false === $templatesJSON) {
            throw new \Exception('Loading templates failed.');
        }

        $this->templates = json_decode($templatesJSON, true);
        if(is_null($this->templates)) {
            throw new \Exception('Loading templates - JSON error.');
        }


        return true;
    }


    public function saveTemplates() {
        $cfg = $GLOBALS['linksConfig'];


        $templatesJSON = json_encode($this->templates);
        if(is_null($templatesJSON)) {
            throw new \Exception('Save templates - JSON error.');
        }

        // TODO Avoid race condition, data lost
        if(false === file_put_contents($cfg['templatesFilename'], $templatesJSON)) {
            throw new \Exception('Save templates failed.');
        }


        return true;
    }
}// Links