Skip to content

Commit

Permalink
Merge pull request #363 from perftools/default-page-options
Browse files Browse the repository at this point in the history
  • Loading branch information
glensc authored Nov 4, 2020
2 parents e7d4d21 + 5953864 commit 1e2bdc4
Show file tree
Hide file tree
Showing 12 changed files with 208 additions and 27 deletions.
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"pimple/pimple": "^3.0",
"slim/slim": "^2.6.3",
"slim/views": "^0.1.0",
"symfony/options-resolver": "^3.3",
"twig/twig": "~1.17"
},
"require-dev": {
Expand Down
56 changes: 55 additions & 1 deletion composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions src/Xhgui/Controller/RunController.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Slim\Http\Response;
use Slim\Slim as App;
use XHGui\AbstractController;
use XHGui\Options\SearchOptions;
use XHGui\Searcher\SearcherInterface;

class RunController extends AbstractController
Expand Down Expand Up @@ -44,14 +45,14 @@ public function index(Request $request, Response $response)
}
$sort = $request->get('sort');

$result = $this->searcher->getAll([
$result = $this->searcher->getAll(new SearchOptions([
'sort' => $sort,
'page' => (int)$request->get('page', SearcherInterface::DEFAULT_PAGE),
'direction' => $request->get('direction'),
'perPage' => (int)$this->app->config('page.limit'),
'conditions' => $search,
'projection' => true,
]);
]));

$title = 'Recent runs';
$titleMap = [
Expand Down
9 changes: 5 additions & 4 deletions src/Xhgui/Controller/WaterfallController.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use Slim\Http\Response;
use Slim\Slim as App;
use XHGui\AbstractController;
use XHGui\Options\SearchOptions;
use XHGui\Profile;
use XHGui\Searcher\SearcherInterface;

Expand All @@ -32,12 +33,12 @@ public function index()
$search[$key] = trim($request->get($key));
}
}
$result = $this->searcher->getAll([
$result = $this->searcher->getAll(new SearchOptions([
'sort' => 'time',
'direction' => 'asc',
'conditions' => $search,
'projection' => true,
]);
]));

$paging = [
'total_pages' => $result['totalPages'],
Expand All @@ -62,12 +63,12 @@ public function query(Request $request, Response $response)
foreach ($keys as $key) {
$search[$key] = $request->get($key);
}
$result = $this->searcher->getAll([
$result = $this->searcher->getAll(new SearchOptions([
'sort' => 'time',
'direction' => 'asc',
'conditions' => $search,
'projection' => true,
]);
]));
$datas = [];
/** @var Profile $r */
foreach ($result['results'] as $r) {
Expand Down
7 changes: 2 additions & 5 deletions src/Xhgui/Db/Mapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,15 @@ public function convert(array $options): array
'conditions' => [],
'sort' => null,
'direction' => null,
'perPage' => 25,
'perPage' => $options['perPage'] ?? SearcherInterface::DEFAULT_PER_PAGE,
];

if (isset($options['conditions'])) {
$result['conditions'] = $this->buildConditions($options['conditions']);
}
$result['direction'] = $this->buildDirection($options);
$result['sort'] = $this->buildSort($options);

if (isset($options['perPage'])) {
$result['perPage'] = $options['perPage'];
}

return $result;
}

Expand Down
61 changes: 61 additions & 0 deletions src/Xhgui/Options/OptionsConfigurator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php

namespace XHGui\Options;

use ArrayAccess;
use ArrayIterator;
use IteratorAggregate;
use Symfony\Component\OptionsResolver\OptionsResolver;

/**
* @see https://symfony.com/doc/3.3/components/options_resolver.html
*/
abstract class OptionsConfigurator implements ArrayAccess, IteratorAggregate
{
/** @var array */
protected $options;

public function __construct(array $options = [])
{
$resolver = new OptionsResolver();
$this->configureOptions($resolver);

$this->options = $resolver->resolve($options);
}

abstract protected function configureOptions(OptionsResolver $resolver);

public function offsetExists($offset): bool
{
return array_key_exists($offset, $this->options);
}

public function offsetGet($offset)
{
return $this->options[$offset];
}

public function offsetSet($offset, $value)
{
if (null === $offset) {
$this->options[] = $value;
} else {
$this->options[$offset] = $value;
}
}

public function offsetUnset($offset)
{
unset($this->options[$offset]);
}

public function getIterator(): ArrayIterator
{
return new ArrayIterator($this->options);
}

public function toArray(): array
{
return $this->options;
}
}
60 changes: 60 additions & 0 deletions src/Xhgui/Options/SearchOptions.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php

namespace XHGui\Options;

use Symfony\Component\OptionsResolver\Options;
use Symfony\Component\OptionsResolver\OptionsResolver;
use XHGui\Searcher\SearcherInterface;

class SearchOptions extends OptionsConfigurator
{
/**
* Options for SearchInterface::getAll
*
* - sort: an array of search criteria (TODO meta.SERVER.REQUEST_TIME => -1 ????)
* - direction: an string, either 'desc' or 'asc'
* - page: an integer, the page to display (e.g. 3)
* - perPage: an integer, how many profiles to display per page (e.g. 25)
* - conditions: an array of criteria to match
* - projection: an array or bool
*/
protected function configureOptions(OptionsResolver $resolver)
{
// NOTE: the null values is trickery to set default values via null value
$defaults = [
'sort' => null,
'direction' => SearcherInterface::DEFAULT_DIRECTION,
'page' => SearcherInterface::DEFAULT_PAGE,
'perPage' => SearcherInterface::DEFAULT_PER_PAGE,
'conditions' => [],
'projection' => false,
];
$resolver->setDefaults($defaults);
$resolver->setRequired(['sort', 'direction', 'page', 'perPage']);

$resolver->setAllowedTypes('sort', ['null', 'string']);
$resolver->setAllowedTypes('direction', ['null', 'string']);
$resolver->setAllowedTypes('page', 'int');
$resolver->setAllowedTypes('perPage', ['null', 'int']);
$resolver->setAllowedTypes('conditions', 'array');
$resolver->setAllowedTypes('projection', ['bool', 'array']);

$resolver->setAllowedValues('direction', [null, 'asc', 'desc']);
$resolver->setAllowedValues('sort', [null, 'time', 'wt', 'cpu', 'mu', 'pmu']);

$resolver->setNormalizer('direction', function (Options $options, $value) use ($defaults) {
if (!$value) {
return $defaults['direction'];
}

return $value;
});
$resolver->setNormalizer('page', function (Options $options, $value) use ($defaults) {
if (!$value) {
return $defaults['page'];
}

return $value;
});
}
}
13 changes: 7 additions & 6 deletions src/Xhgui/Searcher/MongoSearcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use MongoDb;
use MongoId;
use XHGui\Db\Mapper;
use XHGui\Options\SearchOptions;
use XHGui\Profile;

/**
Expand Down Expand Up @@ -206,9 +207,9 @@ public function getAvgsForUrl($url, $search = [])
/**
* {@inheritdoc}
*/
public function getAll($options = [])
public function getAll(SearchOptions $options): array
{
return $this->paginate($options);
return $this->paginate($options->toArray());
}

/**
Expand All @@ -230,7 +231,7 @@ public function truncate()
/**
* {@inheritdoc}
*/
public function saveWatch(array $data)
public function saveWatch(array $data): bool
{
if (empty($data['name'])) {
return false;
Expand Down Expand Up @@ -267,7 +268,7 @@ public function saveWatch(array $data)
/**
* {@inheritdoc}
*/
public function getAllWatches()
public function getAllWatches(): array
{
$cursor = $this->_watches->find();

Expand All @@ -285,7 +286,7 @@ public function truncateWatches()
/**
* {@inheritdoc}
*/
private function paginate($options)
private function paginate(array $options): array
{
$opts = $this->_mapper->convert($options);

Expand Down Expand Up @@ -357,7 +358,7 @@ private function _wrap($data)
/**
* {@inheritdoc}
*/
public function stats()
public function stats(): array
{
return [
'profiles' => 0,
Expand Down
3 changes: 2 additions & 1 deletion src/Xhgui/Searcher/PdoSearcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace XHGui\Searcher;

use XHGui\Db\PdoRepository;
use XHGui\Options\SearchOptions;
use XHGui\Profile;

class PdoSearcher implements SearcherInterface
Expand Down Expand Up @@ -96,7 +97,7 @@ public function getAvgsForUrl($url, $search = [])
/**
* {@inheritdoc}
*/
public function getAll($options = [])
public function getAll(SearchOptions $options): array
{
$page = (int)$options['page'];
$direction = $options['direction'] ?? SearcherInterface::DEFAULT_DIRECTION;
Expand Down
6 changes: 4 additions & 2 deletions src/Xhgui/Searcher/SearcherInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Exception;
use MongoCursor;
use XHGui\Options\SearchOptions;
use XHGui\Profile;

/**
Expand All @@ -12,6 +13,7 @@
interface SearcherInterface
{
const DEFAULT_DIRECTION = 'desc';
const DEFAULT_PER_PAGE = 25;
const DEFAULT_PAGE = 1;

/**
Expand Down Expand Up @@ -80,7 +82,7 @@ public function getAvgsForUrl($url, $search = []);
/**
* Get a paginated set of results.
*
* @param array $options the find options to use
* @param SearchOptions $options the find options to use
* @return array An array of result data with the following keys:
* - results: an array of Profile objects
* - sort: an array of search criteria (TODO meta.SERVER.REQUEST_TIME => -1 ????)
Expand All @@ -89,7 +91,7 @@ public function getAvgsForUrl($url, $search = []);
* - perPage: an integer, how many profiles to display per page (e.g. 25)
* - totalPages: an integer, total number of pages (e.g. 10)
*/
public function getAll($options = []);
public function getAll(SearchOptions $options): array;

/**
* Delete a profile run.
Expand Down
Loading

0 comments on commit 1e2bdc4

Please sign in to comment.