Browse Source

Moved code from subclasses into Base and Collection. Makes easier code and better (more strict) structure to extending classes. Branch ok!

Joachim M. Giæver 6 years ago
parent
commit
77df7744e0

+ 9 - 2
index.php

@@ -27,9 +27,15 @@ try {
 
     $repos = $me->repos()->load();
 
+    $me->orgs()->load();
+
+    /*
     $repo = $repos->get("gogs-php-api-client");
 
-    /*echo "\nNormal repo\n";
+    var_dump($repo->branches()->load());
+     */
+
+    echo "\nNormal repo\n";
     foreach($repos->all() as $key => $repo)
         echo sprintf("* %s: %s\n", $key, $repo->name);
 
@@ -90,6 +96,7 @@ try {
         false,
         true
     );
+    echo "Created repo " . $repo->name . "\n";
 
     echo "\nLooking up repos of test-test-test-#\n";
     foreach($repos->search(array("name" => "test-gogs-api-repo-"))->sort_by()->all() as $key => $repo)
@@ -110,6 +117,7 @@ try {
     } catch (ApiException\HTTPUnexpectedResponse $e) {
         echo $e->getResponse();
     }
+     */
 
     echo "\nLooking up organizations of test-" . $me->username . "\n";
     foreach($orgs->search(array("name" => "test-" . $me->username))->all() as $key => $org)
@@ -126,7 +134,6 @@ try {
         echo sprintf("%s: delete %s\n", $key, $user->delete() ? "true" : "false");
 
 
-    */
     echo "\n\n\nLOG:\n" . join("\n", $client->get_log());
 
 } catch (ApiException\NotAuthorizedException $e) {

+ 7 - 0
src/API/Client.php

@@ -69,6 +69,13 @@ namespace Gogs\API {
             return new Request\Repos($this->url, $this->token);
         }
 
+        /** 
+         * A wrapper function as get_log on Client wont 
+         * return anything. This is bogus, but.... 
+         * this workaround WORKS!
+         *
+         * @return array
+         */
         public function get_log() {
             return (new Request\User($this->url, $this->token))->get_log();
         }

+ 80 - 23
src/API/Request/Base.php

@@ -10,7 +10,7 @@ namespace Gogs\API\Request {
      * and get the cURL functionality.
      *
      * @author Joachim M. Giaever (joachim[]giaever.org)
-     * @abstact
+     * @version 0.1.4
      */
     abstract class Base implements RequestInterface {
 
@@ -141,7 +141,7 @@ namespace Gogs\API\Request {
 
             $ret = $this->method_post(...$args);
 
-            $this->json_set_property($this->json_decode($ret));
+            $this->json_set_property((object)$this->json_decode($ret));
 
             return true;
         }
@@ -186,7 +186,7 @@ namespace Gogs\API\Request {
 
             $this->json_error();
 
-            return $obj;
+            return (object)$obj;
         }
 
         /** 
@@ -215,6 +215,37 @@ namespace Gogs\API\Request {
                 throw new Exception\RequestErrorException(json_last_error_msg(), $err);
         }
 
+        /** 
+         * Set properties for the current object.
+         *
+         * Each child class must implement this to set its data. Will
+         * be called by methods such as `load` and from collection
+         * classes.
+         *
+         * Will return true/false for singel objects but an array on collections.
+         * The array will contain the newly inserted elements. This to prevent
+         * additional iterations.
+         *
+         * This method should also set loaded to true or false, depending
+         * on success or failure.
+         *
+         * @see Collection
+         * @param mixed $obj
+         * @return true|array Array with keys on collections
+         */
+        protected function json_set_property(\stdClass $obj) {
+
+            foreach ($obj as $key => $value) {
+                if ($this->property_exists($key))
+                    $this->{$key} = $value;
+                else
+                    echo "Unknown proerty " . $key . "\n";
+            }
+            $this->loaded = true;   
+
+            return true;
+        }
+
         /** 
          * Get basename of a class (remove namespace).
          * 
@@ -402,26 +433,6 @@ namespace Gogs\API\Request {
             return false;
         }
 
-        /** 
-         * Set properties for the current object.
-         *
-         * Each child class must implement this to set its data. Will
-         * be called by methods such as `load` and from collection
-         * classes.
-         *
-         * Will return true/false for singel objects but an array on collections.
-         * The array will contain the newly inserted elements. This to prevent
-         * additional iterations.
-         *
-         * This method should also set loaded to true or false, depending
-         * on success or failure.
-         *
-         * @see Collection
-         * @param mixed $obj
-         * @return true|array
-         */
-        abstract protected function json_set_property($obj);
-
         /** 
          * Set the scope for the request methods accepted by the child.
          *
@@ -438,6 +449,52 @@ namespace Gogs\API\Request {
          */
         abstract protected function set_scope(string $method);
 
+        /** 
+         * Search for an matching object.
+         *
+         * Methods do OR-ing and not AND-ing by default.
+         *
+         * Params should be key (object property) and value that 
+         * this parameter should match, e.g
+         *
+         * ```
+         * $repo->search(
+         *  "name" => "this",
+         *  "owner" => array(
+         *      "username" => "that"
+         *  )
+         * );
+         * ```
+         *
+         * will match `"this" IN $repo->name OR "that" IN $repo->owner->username` .
+         *
+         * @param array $params Parameters
+         * @param bool $strict Turn search into AND-ing, require match in each field.
+         * @throws Exception\SearchParamException when invalid property
+         * @return true
+         */
+        protected function search(array $params = array(), bool $strict = false) {
+
+            if (empty($params))
+                return false;
+
+            foreach ($params as $key => $value) {
+                if (!$this->property_exists($key))
+                    throw new Exception\SearchParamException("Invalid property exception");
+
+                if (is_array($value) && !$strict && $this->{$key}->search($value, $strict))
+                    return true;
+                else if (is_array($value) && $strict && $this->{$key}->search($value, $strict))
+                    return false;
+                else if (!$strict && stripos($this->{$key}, $value) !== false)
+                    return true;
+                else if ($strict && stripos($this->{$key},$value) === false)
+                    return false;
+            }
+
+            return (!$strict ? false : true);
+        }
+
     }
 
 }

+ 87 - 3
src/API/Request/Branches.php

@@ -2,27 +2,111 @@
 
 namespace Gogs\API\Request {
 
-    final class Brances extends Collection {
+    /** 
+     * Holds a collection of Branches for a Repository.
+     * 
+     * Supported:
+     *  * GET `/repos/username/repo/branches`
+     *
+     * @author Joachim M. Giaever (joachim[]giaever.org)
+     * @version 0.1
+     */
+    final class Branches extends Collection {
         protected $repo;
 
+        /** 
+         * Initialize Brances for a given repo
+         * 
+         * @param Repo $repo The repository
+         */
         public function __construct(string $api_url, string $api_token, Repo $repo) {
             $this->repo = $repo;
             parent::__construct($api_url, $api_token);
         }
 
+        /** 
+         * @see Base
+         */
         protected function set_scope(string $method) {
             switch ($method) {
             case "get":
             case "load":
-                if ($owner == null)
+                if ($this->repo == null)
                     throw new Exception\InvalidMethodRequestException("Missing repository for branches");
 
-                $this->scope = sprintf("/repos/%s/%s/branches", $this->repo->owner, $this->repo->name);
+                $this->scope = sprintf("/repos/%s/%s/branches", $this->repo->owner->username, $this->repo->name);
                 return true;
             }
 
             return false;
         }
+
+        /**
+         * Search for a branch.
+         *
+         * This method doesnt search by a uri, instead it will
+         * load every branch from Gogs and do a match on this.
+         *
+         * Params can be an array of 
+         * ```php
+         * $branches->search(array(
+         *  "name"  => "name",      // alt. "q". required
+         *  "limit" => 10,          // not required, default: 10
+         * ));
+         * ```
+         * By now, this method can be intensive, as it will load
+         * every branch and then do a match on each entry.
+         *
+         * @see Base
+         * @see Collection
+         * @throws Exception\SearchParamException on missing parameters
+         * @return Branches
+         */
+        public function search(array $params = array(), bool $strict = true) {
+
+            if (!isset($params["name"]) && !isset($params["q"]))
+                throw new Exception\SearchParamException("Missing <name|q> parameter");
+
+            if (isset($params["name"])) {
+                $params["q"] = $params["name"];
+                unset($params["q"]);
+            }
+
+            if (!isset($params["limit"]))
+                $params["limit"] = 10;
+
+            $branches = new Branches($this->url, $this->token, $this->repo);
+
+            if (!$this->loaded)
+                $this->load();
+
+            foreach($this->all() as $key => $branch) {
+                if ($branch->search(array("name" => $params["q"]), $strict))
+                    $branches->add($branch, $branch->name);
+
+                if ($branches->len() == $params["limit"])
+                    break;
+            }
+
+            return $branches;
+        }
+
+        /**
+         * @see Collection
+         */
+        public function sort_by(int $flag = Collection::SORT_INDEX) {
+            return $this->sort("ksort");
+        }
+
+        /**
+         * @see Collection
+         */
+        protected function add_object(\stdClass $obj) {
+            $branch = new Branch($this->url, $this->token, $this->repo, $obj->name);
+            $branch->json_set_property($obj);
+            return $this->add($branch, $branch->name);
+        }
+
     }
 
 }

+ 55 - 10
src/API/Request/Collection.php

@@ -7,12 +7,18 @@ namespace Gogs\API\Request {
      *
      * @see Users
      * @author Joachim M. Giaever (joachim[]giaever.org)
-     * @version 0.1.1
+     * @version 0.1.3
      */
     abstract class Collection extends Base implements \Gogs\Lib\ArrayIterator {
 
         private $objs;
 
+        /**
+         * Initialize a collection.
+         *
+         * @see Base
+         * @param Collection $other Collection to initialize from
+         */
         public function __construct(string $api_url, string $api_token, Collection $other = null) {
             parent::__construct($api_url, $api_token);
 
@@ -22,10 +28,6 @@ namespace Gogs\API\Request {
                 $this->objs = new \Gogs\Lib\Collection();
         }
 
-        public function copy() {
-            return new Collection($this);
-        }
-
         /**
          * Add an object to the collection.
          *
@@ -36,7 +38,7 @@ namespace Gogs\API\Request {
          * @param mixed $key Index key to store on
          * @return mixed|int The index key. If key is null the returned value will be an integer.
          */
-        public function add($obj, $key = null) {
+        protected function add($obj, $key = null) {
             $this->objs->set($obj, $key);
             return $key == null ? $this->objs->len() - 1 : $key;
         }
@@ -59,6 +61,13 @@ namespace Gogs\API\Request {
             return $objs->remove($any, $deep);
         }
 
+        /**
+         * @see \Gogs\Lib\ArrayIterator
+         */
+        public function copy() {
+            return new Collection($this);
+        }
+
         /**
          * @see \Gogs\Lib\ArrayIterator
          */
@@ -136,13 +145,49 @@ namespace Gogs\API\Request {
             return $this->objs->copy()->reverse();
         }
 
+        /**
+         * @see Base
+         * @return array
+         */
+        protected function json_set_property(\stdClass $obj) {
+
+            $keys = array();
+
+            if (!is_object($obj) && !is_array($obj))
+                return array();
+
+            if (isset($obj->data))
+                return $this->json_set_property((object)$obj->data);
+
+            foreach($obj as $key => $val)
+                $keys[] = $this->add_object($val);
+
+            return $keys;
+        }
+
+        /**
+         * Search an collection.
+         *
+         * @see Base
+         * @throws Exception\NotImplementedException When not implemented by Collection class.
+         * @return Collection
+         */
+        public function search(array $params = array(), bool $strict = false) {
+            throw new NotImplementedException("::search:: Not implemented by class '" . get_class($this) . "'");
+        }
+
         /** 
-         * Search for an object.
+         * Add an object to the collection with the specific type.
          *
-         * @param array $params Parameters
-         * @return \Gogs\Lib\Collection
+         * Typically it will create an instance of the type that 
+         * the collection will consist of.
+         *
+         * Should call json set property
+         *
+         * @param \stdClass $object 
+         * @return array Key of entry in collection
          */
-        abstract public function search(array $params = array());
+        abstract protected function add_object(\stdClass $object);
 
         /**
          * Sort the object

+ 2 - 13
src/API/Request/Org.php

@@ -11,7 +11,7 @@ namespace Gogs\API\Request {
      *  * POST `/admin/users/username/orgs` (**Requires** admin rights. Curl will throw NotAuthorized exception if not).
      *
      * @author Joachim M. Giaever (joachim[]giaever.org)
-     * @version 0.1.1
+     * @version 0.1.3
      */
     final class Org extends User {
         public $org_description;
@@ -23,8 +23,7 @@ namespace Gogs\API\Request {
         /**
          * Initialize an organization.
          *
-         * @param string $api_url The api-url
-         * @param string $api_token The api-token
+         * @see Base
          * @param User $owner The owner of the organization
          * @param string $oname Organization name
          */
@@ -57,15 +56,6 @@ namespace Gogs\API\Request {
             return false;
         }
 
-        /** 
-         * @see Base
-         */
-        public function search(string $q) {
-            $searchable = sprintf("%s %s %s", $this->full_name, $this->username, $this->description);
-
-            return stripos($searchable, $q) !== false;
-        }
-
         /** 
          * Create a new user
          *
@@ -100,7 +90,6 @@ namespace Gogs\API\Request {
             Base::create($params);
         }
     }
-
 }
 
 ?>

+ 18 - 19
src/API/Request/Orgs.php

@@ -6,11 +6,17 @@ namespace Gogs\API\Request {
      * Orgs is a collection of organizations.
      *
      * @author Joachim M. Giaever (joachim[]giaever.org)
-     * @version 0.1.1
+     * @version 0.1.3
      */
     final class Orgs extends Collection {
         protected $owner;
 
+        /** 
+         * Initialize an organization collection for user.
+         * 
+         * @see Base
+         * @param User $owner The user
+         */
         public function __construct(string $api_url, string $api_token, User $owner) {
             $this->owner = $owner;
             parent::__construct($api_url, $api_token);
@@ -87,11 +93,12 @@ namespace Gogs\API\Request {
          * By now, this method can be intensive, as it will load
          * every organization and then do a match on each entry.
          *
-         * @param array $params Search parameters
-         * @return Orgs
+         * @see Base
+         * @see Collection
          * @throws Exception\SearchParamException on missing parameters
+         * @return Orgs
          */
-        public function search(array $params = array()) {
+        public function search(array $params = array(), bool $strict = false) {
 
             if (!isset($params["name"]) && !isset($params["q"]))
                 throw new Exception\SearchParamException("Missing param <name>|<q>");
@@ -104,7 +111,7 @@ namespace Gogs\API\Request {
             $orgs = new Orgs($this->url, $this->token, $this->owner);
 
             foreach ($this->all() as $key => $org) {
-                if ($org->search($q))
+                if ($org->search(array("username" => $q), $strict))
                     $orgs->add($org, $org->username);
                 if ($orgs->len() == $l)
                     break;
@@ -113,21 +120,13 @@ namespace Gogs\API\Request {
             return $orgs;
         }
 
-        /** 
-         * @see Base
+        /**
+         * @see Collection
          */
-        protected function json_set_property($obj) {
-
-            $rnames = array();
-
-            foreach($obj as $val) {
-                $org = new Org($this->url, $this->token, $this->owner, $val->username);
-                $org->json_set_property($val);
-                $this->add($org, $val->username);
-                $rnames[] = $val->username;
-            }
-
-            return $rnames;
+        protected function add_object(\stdClass $obj) {
+            $org = new Org($this->url, $this->token, $this->owner, $obj->username);
+            $org->json_set_property($obj);
+            return $this->add($org, $obj->username);
         }
 
         /**

+ 14 - 15
src/API/Request/Repo.php

@@ -14,6 +14,7 @@ namespace Gogs\API\Request {
      *  * DELETE `/repos/username/reponame`
      *
      * @author Joachim M. Giaever (joachim[]giaever.org)
+     * @version 0.1.3
      */
     final class Repo extends Base {
         
@@ -40,9 +41,6 @@ namespace Gogs\API\Request {
         public $repo_created_at;
         public $repo_updated_at;
         public $repo_permissions;
-        public $repo_admin;
-        public $repo_push;
-        public $repo_pull;
 
         /**
          * Initialize a repo object.
@@ -50,8 +48,7 @@ namespace Gogs\API\Request {
          * Note that the owner can also be an Org (organization),
          * or any other class that inherits a user.
          *
-         * @param string $api_url The api-url
-         * @param string $api_token The api-token
+         * @see Base
          * @param User $owner The owner of the repo
          * @param string $name The repo name
          */
@@ -99,9 +96,20 @@ namespace Gogs\API\Request {
         }
 
         /** 
+         * Return branches for repository.
+         *
+         * @return Branches
+         */
+        public function branches() {
+            return new Branches($this->url, $this->token, $this);
+        }
+
+        /** 
+         * Overrides Base method as this should set owner as well
+         *
          * @see Base
          */
-        protected function json_set_property($obj) {
+        protected function json_set_property(\stdClass $obj) {
             foreach($obj as $key => $val) {
                 if ($this->property_exists($key)) {
                     switch ($key) {
@@ -122,15 +130,6 @@ namespace Gogs\API\Request {
             return true;
         }
 
-        /** 
-         * @see Base
-         */
-        public function search(string $q) {
-            $searchable = sprintf("%s %s", $this->name, $this->description);
-
-            return stripos($searchable, $q) !== false;
-        }
-
         /** 
          * Create a new repo
          *

+ 35 - 23
src/API/Request/Repos.php

@@ -6,7 +6,7 @@ namespace Gogs\API\Request {
      * Repos is a collection of repos.
      *
      * @author Joachim M. Giaever (joachim[]giaever.org)
-     * @version 0.1.2
+     * @version 0.1.3
      */
     final class Repos extends Collection {
 
@@ -108,10 +108,23 @@ namespace Gogs\API\Request {
          * If the owner is specified the search will be 
          * limited to the actual user.
          *
+         * Params can be an array of 
+         * ```php
+         * $repos->search(array(
+         *  "name"  => "name",      // alt. "q". required
+         *  "limit" => 10,          // not required, default: 10
+         * ));
+         * ```
+         *
+         * If repositories is allready loaded it will do a match
+         * on the existing collection. 
+         *
+         * @see Base
          * @see Collection
+         * @throws Exception\SearchParamException on missing parameters
          * @return Repos
          */
-        public function search(array $params = array()) {
+        public function search(array $params = array(), bool $strict = false) {
 
             if (!isset($params["name"]) && !isset($params["q"]))
                 throw new Exception\SearchParamException("Missing param <name>|<q>");
@@ -121,8 +134,11 @@ namespace Gogs\API\Request {
                 unset($params["name"]);
             }
 
-            if (!isset($params["user"]) || isset($this->owner))
-                $params["user"] = isset($this->owner) ? $this->owner->id : 0;
+            if (!isset($params["uid"]) || isset($this->owner)) {
+                if (!isset($this->owner->id))
+                    $this->owner->load();
+                $params["uid"] = isset($this->owner) ? $this->owner->id : 0;
+            }
 
             if (!isset($params["limit"]))
                 $params["limit"] = 10;
@@ -131,8 +147,16 @@ namespace Gogs\API\Request {
             
             if ($this->loaded) {
                 foreach($this->all() as $key => $repo) {
-                    if ($repo->search($params["q"]))
+                    $search = $repo->search(array(
+                            "name" => $params["q"], 
+                            "description" => $params["q"]
+                        ), 
+                        $strict
+                    );
+
+                    if ($search)
                         $repos->add($repo, $key);
+
                     if ($repos->len() == $params["limit"])
                         break;
                 }
@@ -184,25 +208,13 @@ namespace Gogs\API\Request {
             }
         }
 
-        /** 
-         * @see Base
+        /**
+         * @see Collection
          */
-        protected function json_set_property($obj) {
-            if (isset($obj->data))
-                return $this->json_set_property($obj->data);
-
-            $rnames = array();
-
-            if (is_array($obj)) {
-                foreach ($obj as $key => $val) {
-                    $repo = new Repo($this->url, $this->token);
-                    $repo->json_set_property($val);
-                    $this->add($repo, $repo->full_name);
-                    $rnames[] = $repo->full_name;
-                }
-            }
-
-            return $rnames;
+        protected function add_object(\stdClass $obj) {
+            $repo = new Repo($this->url, $this->token);
+            $repo->json_set_property($obj);
+            return $this->add($repo, $repo->full_name);
         }
     }
 

+ 1 - 24
src/API/Request/User.php

@@ -18,7 +18,7 @@ namespace Gogs\API\Request {
      * @see Orgs
      * 
      * @author Joachim M. Giaever (joachim[]giaever.org)
-     * @version 0.1.1
+     * @version 0.1.3
      */
     class User extends Base {
 
@@ -75,15 +75,6 @@ namespace Gogs\API\Request {
             return true;
         }
 
-        /** 
-         * @see Base
-         */
-        public function search(string $q) {
-            $searchable = sprintf("%s %s %s", $this->full_name, $this->username, $this->login);
-
-            return stripos($searchable, $q) !== false;
-        }
-
         /** 
          * Returns if the user is the authenticated user.
          *
@@ -184,20 +175,6 @@ namespace Gogs\API\Request {
             parent::create($params);
         }
 
-        /** 
-         * @see Base
-         */
-        protected function json_set_property($obj) {
-
-            foreach ($obj as $key => $value) {
-                if ($this->property_exists($key)) {
-                    $this->{$key} = $value;
-                }
-            }
-            $this->loaded = true;   
-
-            return true;
-        }
     }
 
 }

+ 40 - 15
src/API/Request/Users.php

@@ -7,10 +7,13 @@ namespace Gogs\API\Request {
      * 
      * @author Joachim M. Giaever (joachim[]giaever.org)
      * @package request
-     * @version 0.1.1
+     * @version 0.1.3
      */
     final class Users extends Collection {
 
+        /** 
+         * @see Base
+         */
         protected function set_scope(string $method) {
             switch ($method) {
             case "search":
@@ -45,6 +48,12 @@ namespace Gogs\API\Request {
             return $user;
         }
 
+        /** 
+         * Return a user by username.
+         * 
+         * @param string $s The username
+         * @return 
+         */
         public function get(string $s) {
 
             if ($this->by_key($s))
@@ -57,7 +66,25 @@ namespace Gogs\API\Request {
             return $user;
         }
 
-        public function search(array $params = array()) {
+        /**
+         * Search for an user
+         *
+         * Params can be an array of 
+         * ```php
+         * $orgs->search(array(
+         *  "name"  => "name",      // alt. "q". required
+         *  "limit" => 10,          // not required, default: 10
+         * ));
+         * ```
+         * By now, this method can be intensive, as it will load
+         * every organization and then do a match on each entry.
+         *
+         * @see Base
+         * @see Collection
+         * @throws Exception\SearchParamException on missing parameters
+         * @return Orgs
+         */
+        public function search(array $params = array(), bool $strict = false) {
 
             if (!isset($params["name"]) && !isset($params['q']))
                 throw new Exception\SearchParamException("Missing param <name>|<q>");
@@ -84,25 +111,23 @@ namespace Gogs\API\Request {
             return $users;
         }
 
+        /**
+         * @see Collection
+         */
         public function sort_by(int $flag = Collection::SORT_INDEX) {
             return $this->sort("ksort");
         }
 
-        protected function json_set_property($obj) {
-            $rnames[] = array();
-
-            if (isset($obj->data)) {
-                foreach($obj->data as $key => $val) {
-                    $user = new User($this->url, $this->token, $val->username);
-                    $user->json_set_property($val);
-                    $this->add($user, $user->username);
-
-                    $rnames[] = $user->username;
-                }
-            }
 
-            return $rnames;
+        /**
+         * @see Collection
+         */
+        protected function add_object(\stdClass $obj) {
+            $user = new User($this->url, $this->token, $obj->username);
+            $user->json_set_property($obj);
+            $this->add($user, $user->username);
         }
+
     }
 
 }

+ 2 - 2
src/Lib/Collection.php

@@ -8,10 +8,10 @@ namespace Gogs\Lib {
      * which wont be a part of the "request package"
      *
      * @author Joachim M. Giaever (joachim[]giaever.org)
-     * @version 0.1.1
+     * @version 0.1.3
      */
     class Collection implements ArrayIterator {
-        private $objs;
+        private $objs = array();
 
         public function __construct(array $arr = array()) {
             $this->objs = $arr;

+ 1 - 1
src/Lib/Curl/Client.php

@@ -7,7 +7,7 @@ namespace Gogs\Lib\Curl {
      *
      * @author Joachim M. Giaever (joachim[]giaever.org)
      * @package curl
-     * @version 0.1.1
+     * @version 0.1.2
      */
     trait Client {
         private static $log = array();