Skip to content

Commit 17ad7c4

Browse files
committed
Added note on how to make example. Made example finder scan all directories and be cached by redis.
1 parent 9df6cef commit 17ad7c4

File tree

12 files changed

+268
-92
lines changed

12 files changed

+268
-92
lines changed

README.md

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,61 @@ http://local.im6.phpimagick.com - explicitly use ImageMagick 6
1717

1818
http://local.im7.phpimagick.com - explicitly use ImageMagick 7
1919

20-
2120
It will take a few minutes (or more) to come up, as it has to compile ImageMagick 6 and 7, and then Imagick. After the first run, these are cached, so should only take a few seconds.
2221

23-
## PHPStorm stub file
22+
The site is built against the master branch of Imagick at https://github.com/imagick/imagick . As it takes a long time, by default it doesn't rebuild from scratch each time. To force a rebuild against the latest version of Imagick
23+
24+
```
25+
runRebuildLocal.sh
26+
```
27+
28+
containers/imagick_php_base_im7/install_imagemagick.sh
29+
containers/imagick_php_base_im6/install_imagemagick.sh
30+
31+
32+
## Adding examples
33+
34+
There is a list of which examples still need to be added at [phpimagick.com/todo](https://phpimagick.com/todo).
35+
36+
Here are some instructions on adding examples.
37+
38+
### Text example
39+
40+
A text example, is an example that has text as it's output, rather than an image e.g. Imagick::getImageMimeType has [an example added for it in this commit](https://github.com/Imagick/ImagickDemos/commit/9df6cef1051ab6fa90d1bf834a23d083bdf5ab79).
41+
42+
The steps involved are:
43+
44+
1. Add the example to appropriate list in src/example_list.php
45+
46+
getImagickExamples(), getImagickDrawExamples(), getImagickKernelExamples(), getImagickPixelExamples(), getImagickPixelIteratorExamples(), getTutorialExamples()
47+
48+
For each entry in the array, the key is the example name and value is the example controller and example function name. Although most of the time these are the same some examples re-use a controller + function, as there isn't much point duplicating code. e.g. for ImagickDraw 'popClipPath' => 'setClipPath',
49+
50+
2. Create a controller
51+
52+
Usually copying an existing one is a good idea.
53+
54+
3. Mark the example code with a comment with the exact spelling like:
55+
56+
```
57+
//Example Imagick::getImageMimeType
58+
$imagick = new \Imagick($this->imageControl->getImagePath());
59+
60+
$output = 'Imagick::getImageMimeType result is: ';
61+
$output .= $imagick->getImageMimeType();
62+
63+
return $output;
64+
//Example end
65+
```
66+
67+
This makes the example code be picked up and shown on the webpage.
68+
69+
70+
71+
### Standard image example
72+
73+
TODO - write words...
74+
75+
### Standard image example
2476

25-
TODO - move the instructions to the Imagick extension...
77+
TODO - write words...

src/ImagickDemo/Controller/Page.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ public function renderExamplePageMoreSane(
5050
Control $control,
5151
Example $example,
5252
DocHelper $docHelper,
53-
\ImagickDemo\Queue\ImagickTaskQueue $taskQueue
53+
\ImagickDemo\Queue\ImagickTaskQueue $taskQueue,
54+
\ImagickDemo\ExampleFinder\ExampleFinder $exampleFinder
5455
) {
5556
return renderPageHtml(
5657
$categoryNav,
@@ -60,7 +61,8 @@ public function renderExamplePageMoreSane(
6061
$example,
6162
$docHelper,
6263
$varMap,
63-
$taskQueue
64+
$taskQueue,
65+
$exampleFinder
6466
);
6567
}
6668
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace ImagickDemo\ExampleFinder;
6+
7+
use ImagickDemo\CodeExample;
8+
9+
interface ExampleFinder
10+
{
11+
/**
12+
* @param string $category
13+
* @param string $example
14+
* @return CodeExample[]
15+
*/
16+
public function findExamples(string $category, string $example);
17+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?php
2+
3+
declare(strict_types = 1);
4+
5+
namespace ImagickDemo\ExampleFinder;
6+
7+
use ImagickDemo\CodeExample;
8+
use ImagickDemo\ExampleExtractor;
9+
10+
class ExampleSourceFinder implements ExampleFinder
11+
{
12+
/**
13+
* @var \SplFileInfo[]
14+
*/
15+
private $directories;
16+
17+
function __construct() {
18+
// TODO - scan all PHP files again.
19+
$directory = new \RecursiveDirectoryIterator(__DIR__ . '/../../../src');
20+
$iterator = new \RecursiveIteratorIterator($directory);
21+
$this->directories = new \RegexIterator(
22+
$iterator, '/^.+\.php$/i',
23+
\RecursiveRegexIterator::GET_MATCH
24+
);
25+
}
26+
27+
/**
28+
* @param string $category
29+
* @param string $example
30+
* @return CodeExample[]
31+
*/
32+
public function findExamples(string $category, string $example)
33+
{
34+
$examples = [];
35+
36+
foreach ($this->directories as $directory) {
37+
foreach ($directory as $filename) {
38+
// open the file
39+
$fileLines = file($filename);
40+
if (!$fileLines) {
41+
throw new \Exception("Failed to open [" . $filename . "]");
42+
}
43+
$exampleExtractor = new ExampleExtractor($fileLines, $category, $example);
44+
$found_examples = $exampleExtractor->getAllCodeExamples();
45+
array_push($examples, ...$found_examples);
46+
}
47+
}
48+
49+
return $examples;
50+
}
51+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace ImagickDemo\ExampleFinder;
6+
7+
use ImagickDemo\CodeExample;
8+
use Predis\Client as RedisClient;
9+
10+
class RedisExampleFinder implements ExampleFinder
11+
{
12+
private ExampleSourceFinder $exampleSourceFinder;
13+
14+
public function __construct(private RedisClient $redis, private int $ttl)
15+
{
16+
$this->exampleSourceFinder = new ExampleSourceFinder();
17+
}
18+
19+
/**
20+
* @param CodeExample[]
21+
*/
22+
private function examplesToString(array $examples): string
23+
{
24+
$arrays = [];
25+
foreach ($examples as $example) {
26+
$arrays[] = (array)$example;
27+
}
28+
29+
return json_encode_safe($arrays);
30+
}
31+
32+
/**
33+
* @return CodeExample[]
34+
*/
35+
private function examplesFromString(string $encoded)
36+
{
37+
$examples = [];
38+
39+
$array = json_decode_safe($encoded);
40+
foreach ($array as $entry) {
41+
$examples[] = new CodeExample(
42+
$entry['category'],
43+
$entry['function'],
44+
$entry['lines'],
45+
$entry['description'],
46+
$entry['startLine']
47+
);
48+
}
49+
50+
return $examples;
51+
}
52+
53+
public function findExamples(string $category, string $example)
54+
{
55+
$key = 'example_' . $category . '_' . $example;
56+
$result = $this->redis->get($key);
57+
58+
if ($result === null) {
59+
$examples = $this->exampleSourceFinder->findExamples($category, $example);
60+
$string = $this->examplesToString($examples);
61+
$this->redis->set($key, $string, 'EX', $this->ttl);
62+
return $examples;
63+
}
64+
65+
$examples = $this->examplesFromString($result);
66+
return $examples;
67+
}
68+
}

src/ImagickDemo/ExampleSourceFinder.php

Lines changed: 0 additions & 54 deletions
This file was deleted.

src/example_list.php

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,14 @@
55

66
function getImagickDrawExamples()
77
{
8+
// key is the example name
9+
// value is the example controller and example function name
10+
//
11+
// Although most of the time these are the same
12+
// some examples re-use a controller + function, as there
13+
// isn't much point duplicating code.
14+
//
15+
// e.g. for ImagickDraw 'popClipPath' => 'setClipPath',
816
return [
917
'affine' => 'affine',
1018
'arc' => 'arc',
@@ -71,6 +79,14 @@ function getImagickDrawExamples()
7179

7280
function getImagickPixelExamples()
7381
{
82+
// key is the example name
83+
// value is the example controller and example function name
84+
//
85+
// Although most of the time these are the same
86+
// some examples re-use a controller + function, as there
87+
// isn't much point duplicating code.
88+
//
89+
// e.g. for ImagickDraw 'popClipPath' => 'setClipPath',
7490
return [
7591
'construct' => 'construct',
7692
'clear' => 'clear',
@@ -95,6 +111,14 @@ function getImagickPixelExamples()
95111

96112
function getImagickPixelIteratorExamples()
97113
{
114+
// key is the example name
115+
// value is the example controller and example function name
116+
//
117+
// Although most of the time these are the same
118+
// some examples re-use a controller + function, as there
119+
// isn't much point duplicating code.
120+
//
121+
// e.g. for ImagickDraw 'popClipPath' => 'setClipPath',
98122
return [
99123
'clear' => 'clear',
100124
'construct' => 'construct',
@@ -114,6 +138,14 @@ function getImagickPixelIteratorExamples()
114138

115139
function getImagickKernelExamples()
116140
{
141+
// key is the example name
142+
// value is the example controller and example function name
143+
//
144+
// Although most of the time these are the same
145+
// some examples re-use a controller + function, as there
146+
// isn't much point duplicating code.
147+
//
148+
// e.g. for ImagickDraw 'popClipPath' => 'setClipPath',
117149
return [
118150
'addKernel' => 'addKernel',
119151
'addUnityKernel' => 'addUnityKernel',
@@ -128,6 +160,14 @@ function getImagickKernelExamples()
128160

129161
function getTutorialExamples()
130162
{
163+
// key is the example name
164+
// value is the example controller and example function name
165+
//
166+
// Although most of the time these are the same
167+
// some examples re-use a controller + function, as there
168+
// isn't much point duplicating code.
169+
//
170+
// e.g. for ImagickDraw 'popClipPath' => 'setClipPath',
131171
return [
132172
'backgroundMasking' => 'backgroundMasking',
133173
'composite' => 'composite',
@@ -163,6 +203,14 @@ function getTutorialExamples()
163203

164204
function getImagickExamples()
165205
{
206+
// key is the example name
207+
// value is the example controller and example function name
208+
//
209+
// Although most of the time these are the same
210+
// some examples re-use a controller + function, as there
211+
// isn't much point duplicating code.
212+
//
213+
// e.g. for ImagickDraw 'popClipPath' => 'setClipPath',
166214
return [
167215
'adaptiveBlurImage' => 'adaptiveBlurImage',
168216
'adaptiveResizeImage' => 'adaptiveResizeImage',

src/factories.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,4 +211,16 @@ function createTwigForSite(\Auryn\Injector $injector)
211211
}
212212

213213
return $twig;
214+
}
215+
216+
function createExampleFinder(
217+
Predis\Client $redisClient,
218+
Config $config
219+
) {
220+
$cache_time = 60; // 1 minute
221+
if ($config->isProductionEnv() === true) {
222+
$cache_time = 10000000000; // more than 1 minute
223+
}
224+
// return new \ImagickDemo\ExampleFinder\ExampleSourceFinder();
225+
return new \ImagickDemo\ExampleFinder\RedisExampleFinder($redisClient, $cache_time);
214226
}

0 commit comments

Comments
 (0)