<commit_before><?php
/**
 * @category  PHP
 * @author    V.Krishn <<EMAIL>>
 * @copyright Copyright (c) 2016 V.Krishn <<EMAIL>>
 * @license   GPL
 * @link      http://github.com/insteps/aport-api
 * @version   0.0.1
 *
 */

use Phalcon\Loader;
use Phalcon\Mvc\Url;
use Phalcon\Mvc\Micro;
use Phalcon\Di\FactoryDefault;
use Phalcon\Db\Adapter\Pdo\Mysql as PdoMysql;
use Phalcon\Db\Adapter\Pdo\Sqlite as PdoSqlite;
$url = new Url();

// Application configuration data
// -------------------------------
$config['version'] = '0.0.1';
// Setting a full domain as base URI
$url->setBaseUri('http://localhost/aport-api');

$config['apiurl'] = $url->getBaseUri();

// for mysql
$config['mysql'] = array(
    "host" =>     "localhost",
    "username" => "root",
    "password" => "",
    "dbname" =>   "aports"
);
$config['mysql']["persistent"] = false;

// for sqlite
$config['sqlite'] = array(
    "dbname" => "db/aports.db"
);
$config['dbtype'] = 'sqlite';

$config['app']['pglimit'] = 50; #default items per page
// -------------------------------

// Use Loader() to autoload our model
$loader = new \Phalcon\Loader();

$loader->registerDirs(
    array(
        __DIR__ . '/models/'
    )
)->register();

$di = new FactoryDefault();

if( $config['dbtype'] === 'mysql' ) {
    // Set up the database service (mysql)
    $di->set('dbMysql', function () use ($config){
        return new PdoMysql($config['mysql']);
    });
} else {
    // Set up the database service (sqlite)
    $di->set('dbSqlite', function () use ($config){
        return new PdoSqlite($config['sqlite']);
    });
}

//$app = new Micro();
$app = new \Phalcon\Mvc\Micro($di);
$app->config = $config;
$app->myapi = new stdClass;
$app->myapi->pglimit = $config['app']['pglimit'];
$app->myapi->_reqUrl = $app->request->get('_url'); #set default _reqUrl

$app->get('/', function () {
    echo "<h1>Welcome !! </h1>The Json API for Alpine Linux.";
});

$app->get('/about', function () use ($config) {
    $data = array();
    $data['jsonapi'] = array('version' => '1.0');
    $data['meta'] = array (
        'version' => $config['version'],
        'backend' => '',
        'apiurl' => $config['apiurl']
    );
    $data['links'] = array( 'self' => $config['apiurl'].'/about' );
    $data['data'][] = (object)array();
    json_api_encode($data, $this);
});

$app->get('/docs', function () {
    echo "<h1>Api Documents</h1>Todo.";
});

/*

The API consists of the following methods: # TODO - clean text import from lua

  Method  | URL                                    | Action
  ------------------------------------------------------------------------------------------------
  GET     | /$                                     | web.RedirectHandler, {"/packages"}
  GET     | /packages/(.*)/relationships/contents$ | ApiRelationshipsContentRenderer, {aports=aports,model=model}
  GET     | /packages/(.*)/relationships/(.*)$     | ApiPackagesRelationship, {aports=aports,model=model}
  GET     | /packages/(.*)$                        | ApiPackageRenderer {aports=aports,model=model}
  GET     | /packages                              | ApiPackagesRenderer {aports=aports,model=model}
  --contents --------------
  GET     | /contents/(.*)/relationships/packages$ | ApiRelationshipsPackagesRenderer, {aports=aports,model=model}
  GET     | /contents/(.*)$                        | ApiContentRenderer {aports=aports,model=model}
  GET     | /contents                              | ApiContentsRenderer {aports=aports,model=model}
  --static ----------------
  GET     | favicon.ico                            | web.StaticFileHandler, "assets/favicon.ico"
  --others ----------------
  DELETE  | /api/test/100                          | 
  POST    | /api/add/10                            | 
  PUT     | /api/add/10                            | 

*/

// Define routes here

// Retrieves packages
$app->get('/packages', function () use ($app) {

    $data = initJapiData($app, 'packages');

    # get Packages count and figure out paginations
    $limit = $app->myapi->pglimit; $first = "1"; $next = "2";
    $res = Packages::find();
    $tnum = count($res);
    $tpgs = round($tnum/$limit);
    $mod = $tnum%$limit;
    if($mod >= 0) $tpgs = $tpgs+1;

    $offset = isset($app->myapi->offset) ? $app->myapi->offset : 0;

    $data->meta = array(
        'total-pages' => $tpgs,
        'per-page' => $app->myapi->pglimit,
        'count' => $tnum
    );

    $_reqUrl = cleanUri($app->request->get('_url'));
    //$app->myapi->_reqUrl = $_reqUrl;

    if( isset($app->myapi->offset) ) {
      $slink = preg_replace('#\/page.*$#', '', $_reqUrl);
      $next = $app->myapi->pgNext;
      $app->myapi->_reqUrl = $slink;
    } else {
      $slink = $_reqUrl;
    }
    $slink = $app->config['apiurl'] . $slink;

    $data->links = (object)array();
    $data->links->self = $app->config['apiurl'] . $_reqUrl;
    $data->links->next = $slink.'/page/'.$next;
    $data->links->last = $slink.'/page/'.$tpgs;
    $data->links->first = $slink.'/page/'.$first;

    $res = Packages::find(
        array(
            "order" => "id DESC",
            "limit" => $limit,
            "offset" => "$offset"
        )
    );
    $data->data = fmtData($res, 'packages.', $app)->data;
    $data = populate_maintainer($data, $app);

    if($data) json_api_encode($data, $app);

});

// Retrieves packages by paginations (defaults)
$app->get('/packages/page', function () use ($app) {
    $app->myapi->offset = 0;
    $app->myapi->pgNext = 2;
    $app->myapi->pgPrev = 1;
    $app->handle("/packages");
});

// Retrieves packages by paginations
$app->get('/packages/page/{page:[0-9]+}', function ($page) use ($app) {
    $page = (int)$page;
    $app->myapi->offset = $page * $app->myapi->pglimit + 1;
    $app->myapi->pgNext = $page + 1;
    $app->myapi->pgPrev = $app->myapi->offset - 1;
    $app->handle("/packages");
});

// Retrieves packages by id
$app->get('/packages/{pid:[0-9]+}', function ($pid) use ($app) {
    return $app->handle("/packages/pid/$pid");
});

// Retrieves packages by id
$app->get('/packages/pid/{pid:[0-9]+}', function ($pid) use ($app) {
    $data = initJapiData($app, 'packages');

    $res = Packages::find( array( "id = '$pid'", 'limit' => 1) );
    $data->data = fmtData($res, 'packages.id', $app)->data;
    $data = populate_maintainer($data, $app);
    if($data) json_api_encode($data, $app);
});

// Retrieves packages by relationships
$app->get('/packages/{id:[0-9]+}/relationships/{type}', function ($id, $type) use ($app) {

    $rels = array("origins", "depends", "provides", "install_if", "contents");
    return $app->handle("/$type/pid/$id");

    $app->handle('/404');

});

$app->get('/origins/pid/{pid:[0-9]+}', function ($pid) use ($app) {
    return $app->handle("/packages/pid/$pid");
});

$app->get('/install_if/pid/{pid:[0-9]+}', function ($pid) use ($app) {
    $data = initJapiData($app, 'install_if');
    # meta
    $res = Installif::find();
    $tnum = count($res);
    $data->meta = array(
        'total-files' => $tnum
    );
    # data
    $res = Installif::find( array( "pid = '$pid'") );
    $tnum2 = count($res);
    if( ! $tnum2 > 0) return $app->handle('/404');
    $data->meta['pkg-count'] = $tnum2;
    $data->data = fmtData($res, 'install_if.pid', $app)->data;
    return json_api_encode($data, $app);
});

$app->get('/provides/pid/{pid:[0-9]+}', function ($pid) use ($app) {
    $data = initJapiData($app, 'provides');
    # meta
    $res = Provides::find();
    $tnum = count($res);
    $data->meta = array(
        'total-files' => $tnum
    );
    # data
    $res = Provides::find( array( "pid = '$pid'") );
    $tnum2 = count($res);
    if( ! $tnum2 > 0) return $app->handle('/404');
    $data->meta['pkg-count'] = $tnum2;
    $data->data = fmtData($res, 'provides.pid', $app)->data;
    return json_api_encode($data, $app);
});

$app->get('/depends/pid/{pid:[0-9]+}', function ($pid) use ($app) {
    $data = initJapiData($app, 'depends');
    # meta
    $res = Depends::find();
    $tnum = count($res);
    $data->meta = array(
        'total-files' => $tnum
    );
    # data
    $res = Depends::find( array( "pid = '$pid'") );
    $tnum2 = count($res);
    if( ! $tnum2 > 0) return $app->handle('/404');
    $data->meta['pkg-count'] = $tnum2;
    $data->data = fmtData($res, 'depends.pid', $app)->data;
    return json_api_encode($data, $app);
});

// Retrieves package data by its depends(name) relationships (funny relationships)
//  possibly taken as packages that depends on this given named pkg # TODO
$app->get('/depends/{name:[a-z]+.*}/relationships/{type}', function ($name, $type) use ($app) {
    $data = initJapiData($app, 'depends');

    if($type === 'packages') {
        $res = Depends::find( array( "name = '$name'") );
        if( ! count($res) > 0) return $app->handle('/404');
        $pid = $res[0]->pid;

        # ---------------------
        foreach($res as $d) {
            $a[] = $d->pid;
        }
        $l = trim(implode(',', array_unique($a)), ',');
        $l = preg_replace('#\,{2}+#', ',', $l);
        $phql = "SELECT * from Packages where id in ($l) ";
        $res = $app->modelsManager->executeQuery($phql);
        $tnum = count($res);
        $data->meta = array(
            'pkg-count' => $tnum
        );

        $data->data = fmtData($res, 'packages.', $app)->data;
        $data = populate_maintainer($data, $app);

        return json_api_encode($data, $app);
        # ---------------------

        //return $app->handle("/packages/$pid"); # TODO
    }
    $app->handle('/404');
});
<commit_msg>accessing beyond total pages bug fix<commit_after><?php
/**
 * @category  PHP
 * @author    V.Krishn <<EMAIL>>
 * @copyright Copyright (c) 2016 V.Krishn <<EMAIL>>
 * @license   GPL
 * @link      http://github.com/insteps/aport-api
 * @version   0.0.1
 *
 */

use Phalcon\Loader;
use Phalcon\Mvc\Url;
use Phalcon\Mvc\Micro;
use Phalcon\Di\FactoryDefault;
use Phalcon\Db\Adapter\Pdo\Mysql as PdoMysql;
use Phalcon\Db\Adapter\Pdo\Sqlite as PdoSqlite;
$url = new Url();

// Application configuration data
// -------------------------------
$config['version'] = '0.0.1';
// Setting a full domain as base URI
$url->setBaseUri('http://localhost/aport-api');

$config['apiurl'] = $url->getBaseUri();

// for mysql
$config['mysql'] = array(
    "host" =>     "localhost",
    "username" => "root",
    "password" => "",
    "dbname" =>   "aports"
);
$config['mysql']["persistent"] = false;

// for sqlite
$config['sqlite'] = array(
    "dbname" => "db/aports.db"
);
$config['dbtype'] = 'sqlite';

$config['app']['pglimit'] = 50; #default items per page
// -------------------------------

// Use Loader() to autoload our model
$loader = new \Phalcon\Loader();

$loader->registerDirs(
    array(
        __DIR__ . '/models/'
    )
)->register();

$di = new FactoryDefault();

if( $config['dbtype'] === 'mysql' ) {
    // Set up the database service (mysql)
    $di->set('dbMysql', function () use ($config){
        return new PdoMysql($config['mysql']);
    });
} else {
    // Set up the database service (sqlite)
    $di->set('dbSqlite', function () use ($config){
        return new PdoSqlite($config['sqlite']);
    });
}

//$app = new Micro();
$app = new \Phalcon\Mvc\Micro($di);
$app->config = $config;
$app->myapi = new stdClass;
$app->myapi->pglimit = $config['app']['pglimit'];
$app->myapi->_reqUrl = $app->request->get('_url'); #set default _reqUrl

$app->get('/', function () {
    echo "<h1>Welcome !! </h1>The Json API for Alpine Linux.";
});

$app->get('/about', function () use ($config) {
    $data = array();
    $data['jsonapi'] = array('version' => '1.0');
    $data['meta'] = array (
        'version' => $config['version'],
        'backend' => '',
        'apiurl' => $config['apiurl']
    );
    $data['links'] = array( 'self' => $config['apiurl'].'/about' );
    $data['data'][] = (object)array();
    json_api_encode($data, $this);
});

$app->get('/docs', function () {
    echo "<h1>Api Documents</h1>Todo.";
});

/*

The API consists of the following methods: # TODO - clean text import from lua

  Method  | URL                                    | Action
  ------------------------------------------------------------------------------------------------
  GET     | /$                                     | web.RedirectHandler, {"/packages"}
  GET     | /packages/(.*)/relationships/contents$ | ApiRelationshipsContentRenderer, {aports=aports,model=model}
  GET     | /packages/(.*)/relationships/(.*)$     | ApiPackagesRelationship, {aports=aports,model=model}
  GET     | /packages/(.*)$                        | ApiPackageRenderer {aports=aports,model=model}
  GET     | /packages                              | ApiPackagesRenderer {aports=aports,model=model}
  --contents --------------
  GET     | /contents/(.*)/relationships/packages$ | ApiRelationshipsPackagesRenderer, {aports=aports,model=model}
  GET     | /contents/(.*)$                        | ApiContentRenderer {aports=aports,model=model}
  GET     | /contents                              | ApiContentsRenderer {aports=aports,model=model}
  --static ----------------
  GET     | favicon.ico                            | web.StaticFileHandler, "assets/favicon.ico"
  --others ----------------
  DELETE  | /api/test/100                          | 
  POST    | /api/add/10                            | 
  PUT     | /api/add/10                            | 

*/

// Define routes here

// Retrieves packages
$app->get('/packages', function () use ($app) {

    $data = initJapiData($app, 'packages');

    # get Packages count and figure out paginations
    $limit = $app->myapi->pglimit; $first = "1"; $next = "2";
    $res = Packages::find();
    $tnum = count($res);
    $tpgs = round($tnum/$limit);
    $mod = $tnum%$limit;
    // if($mod >= 0) $tpgs = $tpgs+1;
    if($mod >= 0) $tpgs = $tpgs; # TODO

    $offset = isset($app->myapi->offset) ? $app->myapi->offset : 0;

    $data->meta = array(
        'total-pages' => $tpgs,
        'per-page' => $app->myapi->pglimit,
        'count' => $tnum
    );

    $_reqUrl = cleanUri($app->request->get('_url'));
    //$app->myapi->_reqUrl = $_reqUrl;

    if( isset($app->myapi->offset) ) {
      $slink = preg_replace('#\/page.*$#', '', $_reqUrl);
      $next = $app->myapi->pgNext;
      $app->myapi->_reqUrl = $slink;
    } else {
      $slink = $_reqUrl;
    }
    $slink = $app->config['apiurl'] . $slink;

    $data->links = (object)array();
    $data->links->self = $app->config['apiurl'] . $_reqUrl;
    $data->links->next = $slink.'/page/'.$next;
    $data->links->last = $slink.'/page/'.$tpgs;
    $data->links->first = $slink.'/page/'.$first;

    $res = Packages::find(
        array(
            "order" => "id DESC",
            "limit" => $limit,
            "offset" => "$offset"
        )
    );
    $data->data = fmtData($res, 'packages.', $app)->data;
    $data = populate_maintainer($data, $app);

    if($data) json_api_encode($data, $app);

});

// Retrieves packages by paginations (defaults)
$app->get('/packages/page', function () use ($app) {
    $app->myapi->offset = 0;
    $app->myapi->pgNext = 2;
    $app->myapi->pgPrev = 1;
    $app->handle("/packages");
});

// Retrieves packages by paginations
$app->get('/packages/page/{page:[0-9]+}', function ($page) use ($app) {
    $page = (int)$page;

    $limit = $app->myapi->pglimit;
    $res = Packages::find();
    $tnum = count($res);
    $tpgs = round($tnum/$limit);
    if($page > $tpgs) return $app->handle('/404');

    $app->myapi->offset = $page * $app->myapi->pglimit + 1;
    $app->myapi->pgNext = $page + 1;
    $app->myapi->pgPrev = $app->myapi->offset - 1;
    $app->handle("/packages");
});

// Retrieves packages by id
$app->get('/packages/{pid:[0-9]+}', function ($pid) use ($app) {
    return $app->handle("/packages/pid/$pid");
});

// Retrieves packages by id
$app->get('/packages/pid/{pid:[0-9]+}', function ($pid) use ($app) {
    $data = initJapiData($app, 'packages');

    $res = Packages::find( array( "id = '$pid'", 'limit' => 1) );
    $data->data = fmtData($res, 'packages.id', $app)->data;
    $data = populate_maintainer($data, $app);
    if($data) json_api_encode($data, $app);
});

// Retrieves packages by relationships
$app->get('/packages/{id:[0-9]+}/relationships/{type}', function ($id, $type) use ($app) {

    $rels = array("origins", "depends", "provides", "install_if", "contents");
    return $app->handle("/$type/pid/$id");

    $app->handle('/404');

});

$app->get('/origins/pid/{pid:[0-9]+}', function ($pid) use ($app) {
    return $app->handle("/packages/pid/$pid");
});

$app->get('/install_if/pid/{pid:[0-9]+}', function ($pid) use ($app) {
    $data = initJapiData($app, 'install_if');
    # meta
    $res = Installif::find();
    $tnum = count($res);
    $data->meta = array(
        'total-files' => $tnum
    );
    # data
    $res = Installif::find( array( "pid = '$pid'") );
    $tnum2 = count($res);
    if( ! $tnum2 > 0) return $app->handle('/404');
    $data->meta['pkg-count'] = $tnum2;
    $data->data = fmtData($res, 'install_if.pid', $app)->data;
    return json_api_encode($data, $app);
});

$app->get('/provides/pid/{pid:[0-9]+}', function ($pid) use ($app) {
    $data = initJapiData($app, 'provides');
    # meta
    $res = Provides::find();
    $tnum = count($res);
    $data->meta = array(
        'total-files' => $tnum
    );
    # data
    $res = Provides::find( array( "pid = '$pid'") );
    $tnum2 = count($res);
    if( ! $tnum2 > 0) return $app->handle('/404');
    $data->meta['pkg-count'] = $tnum2;
    $data->data = fmtData($res, 'provides.pid', $app)->data;
    return json_api_encode($data, $app);
});

$app->get('/depends/pid/{pid:[0-9]+}', function ($pid) use ($app) {
    $data = initJapiData($app, 'depends');
    # meta
    $res = Depends::find();
    $tnum = count($res);
    $data->meta = array(
        'total-files' => $tnum
    );
    # data
    $res = Depends::find( array( "pid = '$pid'") );
    $tnum2 = count($res);
    if( ! $tnum2 > 0) return $app->handle('/404');
    $data->meta['pkg-count'] = $tnum2;
    $data->data = fmtData($res, 'depends.pid', $app)->data;
    return json_api_encode($data, $app);
});

// Retrieves package data by its depends(name) relationships (funny relationships)
//  possibly taken as packages that depends on this given named pkg # TODO
$app->get('/depends/{name:[a-z]+.*}/relationships/{type}', function ($name, $type) use ($app) {
    $data = initJapiData($app, 'depends');

    if($type === 'packages') {
        $res = Depends::find( array( "name = '$name'") );
        if( ! count($res) > 0) return $app->handle('/404');
        $pid = $res[0]->pid;

        # ---------------------
        foreach($res as $d) {
            $a[] = $d->pid;
        }
        $l = trim(implode(',', array_unique($a)), ',');
        $l = preg_replace('#\,{2}+#', ',', $l);
        $phql = "SELECT * from Packages where id in ($l) ";
        $res = $app->modelsManager->executeQuery($phql);
        $tnum = count($res);
        $data->meta = array(
            'files' => $tnum
        );

        $data->data = fmtData($res, 'packages.', $app)->data;
        $data = populate_maintainer($data, $app);

        return json_api_encode($data, $app);
        # ---------------------

        //return $app->handle("/packages/$pid"); # TODO
    }
    $app->handle('/404');
});

{'fraction_non_alphanumeric': 0.24025202706192222, 'fraction_numerical': 0.009089500593916233, 'mean_word_length': 2.461565963532356, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 294, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2420261', 'n_tokens_mistral': 6769, 'n_tokens_neox': 6602, 'n_words': 1318}