Completed
Push — master ( 4f6354...e74d94 )
by Thomas
02:57
created

Lazy::addClasses()   B

Complexity

Conditions 5
Paths 3

Duplication

Lines 0
Ratio 0 %

Size

Total Lines 22
Code Lines 14

Code Coverage

Tests 15
CRAP Score 5

Importance

Changes 0
Metric Value
cc 5
eloc 14
nc 3
nop 2
dl 0
loc 22
ccs 15
cts 15
cp 1
crap 5
rs 8.6737
c 0
b 0
f 0
1
<?php
2
/**
3
 * A list of lazy initialized loaders.
4
 *
5
 * @license http://www.opensource.org/licenses/mit-license.php The MIT License
6
 * @copyright Copyright (c) 2009-2017 FluentDOM Contributors
7
 */
8
9
namespace FluentDOM\Loader {
10
11
  use FluentDOM\DOM\Document;
12
  use FluentDOM\DOM\DocumentFragment;
13
  use FluentDOM\Loadable;
14
15
  /**
16
   * A list of lazy initialized loaders.
17
   */
18
  class Lazy implements Loadable {
19
20
    private $_list = [];
21
22 15
    public function __construct(array $loaders = []) {
23 15
      foreach ($loaders as $contentType => $loader) {
24 10
        $this->add($contentType, $loader);
25
      }
26 14
    }
27
28
    /**
29
     * Add a loader to the list
30
     *
31
     * @param string $contentType
32
     * @param Loadable|callable $loader
33
     * @throws \UnexpectedValueException
34
     */
35 14
    public function add(string $contentType, $loader) {
36 14
      $contentType = $this->normalizeContentType($contentType);
37 14
      if ($loader instanceof Loadable || is_callable($loader)) {
38 13
        $this->_list[$contentType] = $loader;
39 13
        return;
40
      }
41 1
      throw new \UnexpectedValueException(
42 1
        sprintf(
43 1
          'Lazy loader for content type "%s" is not a callable or FluentDOM\Loadable',
44 1
          $contentType
45
        )
46
      );
47
    }
48
49
    /**
50
     * Add loader classes for different types
51
     *
52
     * @param array[] $classes ['class' => ['type/one', 'type/two'], ...]
53
     * @param string $namespace
54
     * @throws \LogicException
55
     * @throws \UnexpectedValueException
56
     */
57 4
    public function addClasses($classes, string $namespace = '') {
58 4
      foreach ($classes as $loader => $types) {
59 4
        $class = str_replace(['\\\\\\', '\\\\'], '\\', $namespace.'\\'.$loader);
60 4
        $callback = function() use ($class) {
61 3
          if (!class_exists($class)) {
62 1
            throw new \LogicException(
63 1
              sprintf(
64 1
                'Loader class "%s" not found.', $class
65
              )
66
            );
67
          }
68 2
          return new $class;
69 4
        };
70 4
        if (is_array($types)) {
71 2
          foreach ($types as $type) {
72 2
            $this->add($type, $callback);
73
          }
74
        } else {
75 2
          $this->add((string)$types, $callback);
76
        }
77
      }
78 4
    }
79
80
    /**
81
     * @throws \UnexpectedValueException
82
     * @param string $contentType
83
     * @return bool|Loadable
84
     */
85 10
    public function get(string $contentType) {
86 10
      $contentType = $this->normalizeContentType($contentType);
87 10
      if (isset($this->_list[$contentType])) {
88 8
        if (!($this->_list[$contentType] instanceof Loadable)) {
89 7
          $this->_list[$contentType] = call_user_func($this->_list[$contentType]);
90
        }
91 7
        if (!($this->_list[$contentType] instanceof Loadable)) {
92 1
          unset($this->_list[$contentType]);
93 1
          throw new \UnexpectedValueException(
94 1
            sprintf(
95 1
              'Lazy loader for content type "%s" did not return a FluentDOM\Loadable',
96 1
              $contentType
97
            )
98
          );
99
        }
100 6
        return $this->_list[$contentType];
101
      }
102 2
      return FALSE;
103
    }
104
105
    /**
106
     * @param string $contentType
107
     * @return bool
108
     */
109 3
    public function supports(string $contentType): bool {
110 3
      $contentType = $this->normalizeContentType($contentType);
111 3
      return isset($this->_list[$contentType]);
112
    }
113
114
    /**
115
     * @param mixed $source
116
     * @param mixed $contentType
117
     * @param array|\Traversable|Options $options
118
     * @return Document|Result|NULL
119
     */
120 2 View Code Duplication
    public function load($source, string $contentType, $options = []) {
121 2
      $contentType = $this->normalizeContentType($contentType);
122 2
      if ($loader = $this->get($contentType)) {
123 1
        return $loader->load($source, $contentType, $options);
124
      }
125 1
      return NULL;
126
    }
127
128
    /**
129
     * @param mixed $source
130
     * @param string $contentType
131
     * @param array|\Traversable|Options $options
132
     * @return DocumentFragment|NULL
133
     * @throws \UnexpectedValueException
134
     */
135 2 View Code Duplication
    public function loadFragment($source, string $contentType, $options = []) {
136 2
      $contentType = $this->normalizeContentType($contentType);
137 2
      if ($loader = $this->get($contentType)) {
138 1
        return $loader->loadFragment($source, $contentType, $options);
139
      }
140 1
      return NULL;
141
    }
142
143
    /**
144
     * @param string $contentType
145
     * @return string
146
     */
147 15
    private function normalizeContentType(string $contentType): string {
148 15
      return strtolower(trim($contentType));
149
    }
150
  }
151
}