Completed
Push — master ( d43e8c...849906 )
by Peter
04:20
created

ApiUrl::setRoot()   B

Complexity

Conditions 6
Paths 7

Size

Total Lines 28
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 28
rs 8.439
c 0
b 0
f 0
cc 6
eloc 14
nc 7
nop 1
1
<?php
2
3
/*
4
 * To change this license header, choose License Headers in Project Properties.
5
 * To change this template file, choose Tools | Templates
6
 * and open the template in the editor.
7
 */
8
9
namespace Maslosoft\Zamm;
10
11
use Maslosoft\Zamm\Interfaces\SourceAccessorInterface;
12
use Maslosoft\Zamm\Traits\SourceMagic;
13
use UnexpectedValueException;
14
15
/**
16
 * Api Url generator
17
 *
18
 * @author Piotr Maselkowski <pmaselkowski at gmail.com>
19
 */
20
class ApiUrl implements SourceAccessorInterface
21
{
22
23
	use SourceMagic;
24
25
	private static $sources = [];
26
	private $dotName = '';
27
	private $source = '';
28
29
	public function __construct($className = null, $text = '')
30
	{
31
		$this->dotName = str_replace('\\', '.', $className);
32
33
34
		// Many source found, search for proper api source
35
		$url = '';
36
37
		$search = self::normalize($className);
38
		foreach (self::$sources as $url => $nss)
39
		{
40
			foreach ($nss as $ns)
41
			{
42
				if (empty($ns) || !is_string($url))
43
				{
44
					continue;
45
				}
46
				$pos = strpos($search, $ns);
47
48
				if ($pos === false)
49
				{
50
					continue;
51
				}
52
				if ($pos === 0)
53
				{
54
					$this->source = $url;
55
					break;
56
				}
57
			}
58
		}
59
60
		// Last resort url assigning
61
		if (empty($this->source))
62
		{
63
			$this->source = $url;
64
		}
65
	}
66
67
	/**
68
	 * Set root url of current project API. This can be relative or absolute url.
69
	 *
70
	 * Set url for many projects with namespaces - this allows cross-linking different projects:
71
	 *
72
	 * ```
73
	 * ApiUrl::setRoot([
74
	 * 		'/mangan/api' => 'Maslosoft\\Mangan\\'
75
	 * 		'/addendum/api' => 'Maslosoft\\Addendum\\'
76
	 * ]);
77
	 * ```
78
	 *
79
	 * Could also be used for one project, but might result in wrong url if
80
	 * used on classes outside of project:
81
	 *
82
	 * ```
83
	 * ApiUrl::setRoot('/mangan/api);
84
	 * ```
85
	 *
86
	 *
87
	 * @param string $apiUrl
88
	 */
89
	public static function setRoot($apiUrl)
90
	{
91
		if (is_string($apiUrl))
92
		{
93
			self::$sources[rtrim($apiUrl, '/')] = [];
94
		}
95
		elseif (is_array($apiUrl))
96
		{
97
			$urls = [];
98
			foreach ($apiUrl as $url => $ns)
99
			{
100
				if (!is_array($ns))
101
				{
102
					$ns = [$ns];
103
				}
104
				foreach ($ns as $nsIndex => $oneNs)
105
				{
106
					$ns[$nsIndex] = self::normalize($oneNs);
107
				}
108
				$urls[rtrim($url, '/')] = $ns;
109
			}
110
			self::$sources = array_merge(self::$sources, $urls);
111
		}
112
		else
113
		{
114
			throw new UnexpectedValueException(sprintf('Expected `apiUrl` to be string or array, got `%s`', gettype($apiUrl)));
115
		}
116
	}
117
118
	public function method($name)
119
	{
120
		// https://df.home/zamm/api/class-Maslosoft.Zamm.Decorators.AbstractDecorator.html#_decorate
121
		return sprintf('%s/class-%s.html#_%s', $this->source, $this->dotName, $name);
122
	}
123
124
	public function property($name)
125
	{
126
		// https://df.home/zamm/api/class-Maslosoft.Zamm.Zamm.html#$decorators
127
		return sprintf('%s/class-%s.html#$%s', $this->source, $this->dotName, $name);
128
	}
129
130
	public static function __callStatic($name, $arguments)
131
	{
132
133
	}
134
135
	public function __toString()
136
	{
137
		return sprintf('%s/class-%s.html', $this->source, $this->dotName);
138
	}
139
140
	/**
141
	 * Ensure that name starts and ends with slash
142
	 * @param string $name
143
	 * @return string
144
	 */
145
	private static function normalize($name)
146
	{
147
		return sprintf('\\%s\\', trim($name, '\\'));
148
	}
149
150
}
151