Return to Snippet

Revision: 27521
at June 13, 2010 10:03 by minky


Initial Code
<?php

    class calibre {

        public $settings = array(
            "server"    => array(
                // calibre server details
                "host"      => "minky.mine.nu",
                "port"      => "8080",
                "username"  => "",
                "password"  => "",
            ),
            // calibre server tokens/values
            "start"     => 0,
            "num"       => 20,
            "order"     => "ascending",
            "sort"      => "title",
            "search"    => "",
        );

        // .. curl data
        private $curl_meta, $curl_data;

        // xml, object (simplexml) data
        private $xml, $object;

        // html data
        private $paginate;

        private $authors    = array();
        private $series     = array();
        
        public function __construct() {}
        
        public function debug() {
            
            echo "<pre>";
            print_r($this);
            echo "</pre>";
            die;
            
        }

        private function fetch_query_string() {
            
            $data = $this->settings;
            
            unset($data["server"]);
            
            return "?". http_build_query($data, "&amp;");
        
        }
        
        private function parse_response() {

            try {

                $this->object = new SimpleXMLElement($this->curl_data);
            
                $this->xml = $this->object->asXML();

            } catch(Exception $e) {
                throw new CalibreException($e->getMessage());
            }
            
        }
        
        public function set($settings) {
            
            if(is_array($settings)) {

                foreach($settings AS $key => $value) {

                    if(empty($key) || empty($value)) continue;

                    $this->settings[$key] = $value;

                }
            }
            
            return $this;
            
        }
        
        public function fetch_library() {

            if(empty($this->settings["server"]["host"]) || empty($this->settings["server"]["port"]))
                throw new CalibreException('No Server/Port Defined! <a class="button define server" href="#define">Define Server Settings</a>');

            $qs = $this->fetch_query_string();

            $curl = curl_init();

            if(!empty($this->settings["server"]["username"]) && !empty($this->settings["server"]["password"])) {

                curl_setopt($curl, CURLOPT_USERPWD, "{$this->settings["server"]["username"]}:{$this->settings["server"]["password"]}");
                curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY);

            }
            
            curl_setopt_array($curl, array(
                CURLOPT_RETURNTRANSFER => TRUE,
                CURLOPT_HEADER => 0,
                CURLOPT_USERAGENT => "",
                CURLOPT_URL => "http://{$this->settings["server"]["host"]}/library{$qs}",
                CURLOPT_PORT => $this->settings["server"]["port"],
                CURLOPT_TIMEOUT => 3,
            ));
            
            $this->curl_data = curl_exec($curl);
            $this->curl_meta = curl_getinfo($curl);
            
            curl_close($curl);

            if($this->curl_data === FALSE)
                throw new CalibreException('cURL Data is empty! Is the Server running? <a class="button define server" href="#define">Define Server Settings</a>');

            try {
                $this->parse_response();
            } catch(CalibreException $e) {
                throw new CalibreException($e->getMessage());
            }

            return $this;

        }

        public function as_json() {
            return json_encode($this->object);
        }

        public function as_object() {
            return $this->object;
        }
        
        public function as_xml() {
            return $this->xml;
        }
        
        private function page_select($page_count, $current = 1) {
            
            $options = array();
            
            for($i = 1; $i <= $page_count; $i++) {
                
                $selected = $i == $current ? "selected" : "" ;
                
                $options[] = '<option value="'. $i .'" '. $selected .'>'. $i .'</option>';
                
            }
            
            return '<select class="paginate">'. implode("", $options) .'</select>';
            
        }

        public function paginate($total) {
            
            $page_count = ceil($total / $this->settings["num"]);

            $current = ceil($this->settings["start"] / $this->settings["num"]);
            $current = empty($current) ? 1 : $current ;
            
            $prev = $current == 1 ? 1 : $current - 1 ;
            $next = $current == $page_count ? $page_count : $current + 1 ;
            
            $links = array();

            $links[] = '
<section class="paginate">
    <ul>
        <li class="prev">
            <a href="page/'. $prev .'" class="button">&laquo; Prev</a>
        </li>
        <li class="current">'. $this->page_select($page_count, $current) .' of '. $page_count .'</li>
        <li class="next">
            <a href="page/'. $next .'" class="button">Next &raquo;</a>
        </li>
    </ul>
</section>
            ';

            $this->paginate = implode("", $links);

        }
        
        public function parse_html($book) {

            $data = array();
            
            foreach($book->attributes() AS $key => $value) {

                if($key == "formats") {
                    $data[$key] = $this->parse_formats((string) $value, $data["title"], $data["id"]);
                } elseif($key == "authors") {
                    $data[$key] = $this->parse_authors((string) $value);
                } elseif($key == "series") {
                    $data[$key] = $this->parse_series((string) $value);
                } else {
                    $data[$key] = (string) $value;
                }
            }

            return $data;
        
        }
        
        private function parse_formats($format, $title, $id) {
        
            $formats = stristr($format, ",") ? explode(",", $format) : array($format) ;
            
            $output = array();
            
            foreach($formats AS $f)
                $output[] = '<a href="http://'. $this->settings["server"]["host"] .':'. $this->settings["server"]["port"] .'/get/'. strtolower($f) .'/'. $title .'_'. $id .'.'. strtolower($f) .'" class="file button">'. strtoupper($f) .'</a>';
            
            return implode("", $output);
            
        }
        
        private function parse_authors($authors) {
            
            $authors = stristr($authors, ",") ? explode(",", $authors) : array($authors) ;
            
            $output = array();
            
            foreach($authors AS $author)
                $output[] = ucwords(trim($author));

            $this->authors = array_merge($this->authors, $output);

            return implode("", $output);
            
        }
        
        private function parse_series($series) {
            return empty($series) ? "Unknown" : ucwords($series) ;
        }

        public function as_html() {
            
            $books = array();

            $attrib = $this->object->attributes();
            
            $this->paginate((int) $attrib->total);
            
            foreach($this->object->children() AS $key => $value) {
                
                $book = $this->parse_html($value);

                $this->series[] = $book["series"];
                
                $books[] = '
<article class="book">
    
    <header><h2>'. $book["title"] .'</h2></header>
    
    <section class="content">

        <section class="details float-left">
        
            <ul>
            
                <li class="author">
                    <span class="label">Author</span>
                    <span class="data">'. $book["authors"] .'</span>
                </li>
                <li class="author">
                    <span class="label">Series</span>
                    <span class="data">'. $book["series"] .'</span>
                </li>
                <li class="formats">
                    <span class="label">Download</span>
                    <span class="data">'. $book["formats"] .'</span>
                </li>

            </ul>
        
        </section>

        <section class="image float-right">

            <img src="http://'. $this->settings["server"]["host"] .':'. $this->settings["server"]["port"] .'/get/cover/'. $book["id"] .'" alt="Cover Image" />

        </section>
        
    </section>
    
</article>
                ';
            }
            
            $paginate = $this->paginate;

            return $paginate . implode("", $books) . $paginate;
            
        }

    }

    class CalibreException extends Exception {
        public function __construct($message, $code = 0) {
            parent::__construct($message, $code);
        }
    }
    // 
    $calibre = new calibre;
    // 
    $sort   = empty($_GET['sort']) ? $calibre->settings["sort"] : $_GET['sort'] ;
    $order  = empty($_GET['order']) ? $calibre->settings["order"] : $_GET['order'] ;
    $search = empty($_GET['search']) ? "" : $_GET['search'] ;
    //
    $start  = empty($_GET['start']) ? 0 : (int) $_GET['start'] ;
    $per_page = $calibre->settings["num"];
    
    $server = array(
        "host"      => $_GET['host'],
        "port"      => $_GET['port'],
        "username"  => $_GET['username'],
        "password"  => $_GET['password'],
    );
    //
    $settings = array(
        "start" => $start * $per_page,
        "num"   => $per_page,
        "sort"  => $sort,
        "order" => $order,
        "search"=> $search,
        "server"=> $server,
    );

    // try getting library as html
    try {
        echo $calibre->set($settings)->fetch_library()->as_html();
    } catch(CalibreException $e) {
        echo '<article class="error">'. $e->getMessage() .'</article>';
    }
    
    die;
    
    //$calibre->debug(); // very long page
    
?>

Initial URL
http://www.pixaweb.co.uk/calibre/

Initial Description
forms part of our Calibre Remote Web App. basically an alternate gui for calibre ebooks content-server.

Initial Title
Calibre Remote - PHP5 Class

Initial Tags
curl, php

Initial Language
PHP