PageRenderTime 27ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 0ms

/src/Finnegan/Definitions/ModelDefinition.php

https://gitlab.com/fsavina/finncds-temporary
PHP | 436 lines | 215 code | 79 blank | 142 comment | 14 complexity | a82a28dc7d93726162a677036db856b9 MD5 | raw file
  1. <?php
  2. namespace Finnegan\Definitions;
  3. use Finnegan\Contracts\Auth\AuthorizationException;
  4. use Illuminate\Support\Arr;
  5. use Illuminate\Support\Str;
  6. class ModelDefinition extends Definition
  7. {
  8. const DEFAULT_TABLE_NAMESPACE = 'finn_';
  9. /**
  10. * The list of the system tables
  11. * @var array
  12. */
  13. protected static $systemTables = [ 'migrations' ];
  14. /**
  15. * The table namespace for the definition
  16. * @var string
  17. */
  18. protected $tableNamespace;
  19. /**
  20. * The JSON schemas for the validation
  21. * @var array
  22. */
  23. protected $schemas = [ 'model' ];
  24. /**
  25. * @param \Finnegan\Definitions\DefinitionsFactory $factory
  26. */
  27. public function init ( DefinitionsFactory $factory )
  28. {
  29. if ( is_null ( $this->context ) )
  30. {
  31. throw new \Exception('No loading context set');
  32. }
  33. if ( $namespace = $factory -> config ( 'module.table_namespace' ) )
  34. {
  35. $this -> tableNamespace = $namespace;
  36. }
  37. $this -> loadIncludes ( $factory )
  38. -> loadComponents ( $factory );
  39. //-> loadAuthExtensions ( $factory );
  40. }
  41. /**
  42. * Extend the current definition with the included definitions
  43. * @param \Finnegan\Definitions\DefinitionsFactory $factory
  44. * @return \Finnegan\Definitions\ModelDefinition
  45. * @throws \Exception
  46. */
  47. protected function loadIncludes ( DefinitionsFactory $factory )
  48. {
  49. if ( isset ( $this -> data [ 'include' ] ) )
  50. {
  51. $includes = ( array ) $this -> data [ 'include' ];
  52. foreach ( $includes as $include )
  53. {
  54. $included = $factory -> load ( $include );
  55. $data = $included -> toArray ();
  56. $table = Arr::get ( $data, 'storage.table' );
  57. if ( ! $table )
  58. {
  59. Arr::set ( $data, 'storage.table', $included->table () );
  60. } elseif ( is_array ( $table ) and ! Arr::get ( $table, 'name' ) )
  61. {
  62. Arr::set ( $data, 'storage.table.name', $included->table () );
  63. }
  64. $this -> merge ( $data );
  65. }
  66. }
  67. return $this;
  68. }
  69. /**
  70. * Extend the current definition with the required components
  71. * @param \Finnegan\Definitions\DefinitionsFactory $factory
  72. * @return \Finnegan\Definitions\ModelDefinition
  73. */
  74. protected function loadComponents ( DefinitionsFactory $factory )
  75. {
  76. if ( isset ( $this -> data [ 'components' ] ) )
  77. {
  78. $components = ( array ) $this -> data [ 'components' ];
  79. foreach ( $components as $componentName )
  80. {
  81. try {
  82. $component = $factory -> load ( "component:$componentName" );
  83. } catch (AuthorizationException $e)
  84. {
  85. continue;
  86. }
  87. $this -> merge ( Arr::get ( $component -> toArray (), 'component', [ ] ) );
  88. }
  89. }
  90. return $this;
  91. }
  92. /**
  93. * Check if the current definition has a component
  94. * @param string $component
  95. * @return boolean
  96. */
  97. public function hasComponent ( $component )
  98. {
  99. return in_array ( $component, ( array ) $this -> get ( 'components', [ ] ) );
  100. }
  101. /**
  102. * Overwrite specific user role configurations
  103. * @param DefinitionsFactory $factory
  104. * @return ModelDefinition
  105. */
  106. /*protected function loadAuthExtensions ( DefinitionsFactory $factory )
  107. {
  108. if ( ! $this -> isUnguarded() )
  109. {
  110. $guard = $factory->auth ();
  111. $if = $this -> get ( 'auth.if' );
  112. if ( is_array ( $if ) and count ( $if ) and $guard->check () )
  113. {
  114. foreach ( $if as $roleConfig )
  115. {
  116. if ( ! $guard->user ()->achieve ( $roleConfig [ 'role' ] ) )
  117. {
  118. continue;
  119. }
  120. $this -> merge ( $roleConfig [ 'extend' ], true );
  121. }
  122. }
  123. }
  124. return $this;
  125. }*/
  126. public function mustVerify ()
  127. {
  128. return $this -> get ( 'storage.verify', true );
  129. }
  130. public function verify ( DefinitionsFactory $factory )
  131. {
  132. $factory->validator ( 'storage' )->check ( $this );
  133. }
  134. /**
  135. * Get the namespace for the current model table
  136. * @return string
  137. */
  138. protected function tableNamespace ()
  139. {
  140. return $this -> tableNamespace ? : static :: DEFAULT_TABLE_NAMESPACE;
  141. }
  142. /**
  143. * Get the table name
  144. * @return string
  145. * @throws AuthorizationException
  146. */
  147. public function table ()
  148. {
  149. $table = $this -> get ( 'storage.table', $this -> name () );
  150. $table = is_string ( $table ) ? $table : Arr::get ( $table, 'name', $this -> name () );
  151. $table = $this -> wrapTableName ( $table );
  152. if ( static :: isSystemTable ( $table ) and ! $this -> get ( 'storage.table.unguard' ) )
  153. {
  154. throw new AuthorizationException ( "The '$table' table is a system table. Set storage.table.unguard=true on your definition to gain access." );
  155. }
  156. return $table;
  157. }
  158. /**
  159. * Apply the given namespace to the table name
  160. * @param string $table
  161. * @return string
  162. */
  163. public function wrapTableName ( $table )
  164. {
  165. $namespace = $this -> tableNamespace ();
  166. if ( $this -> get ( 'storage.table.namespace', true ) and ! starts_with ( $table, $namespace ) )
  167. {
  168. $table = "{$namespace}{$table}";
  169. }
  170. return $table;
  171. }
  172. /**
  173. * Check if the given table is a system table
  174. * @param string $table
  175. * @return boolean
  176. */
  177. protected static function isSystemTable ( $table )
  178. {
  179. return in_array ( $table, static :: $systemTables );
  180. }
  181. /**
  182. * Get the relation pivot table name
  183. * @param string $relation
  184. * @return string
  185. */
  186. public function relationPivotTable ( $relation )
  187. {
  188. $table = $this -> get ( "relations.{$relation}.table" );
  189. if ( strlen ( $table ) )
  190. {
  191. return $this -> wrapTableName ( $table );
  192. }
  193. $base = Str :: snake ( $this -> name () );
  194. // If there's no definition the relation name is the related object
  195. $related = $this -> get ( "relations.{$relation}.definition", $relation );
  196. $related = snake_case ( $related );
  197. $models = [ $related, $base ];
  198. sort ( $models );
  199. return $this -> wrapTableName ( strtolower ( implode ( '_', $models ) ) );
  200. }
  201. /**
  202. * Get the translations table name
  203. * @return string
  204. */
  205. public function translationsTable ()
  206. {
  207. $table = Str :: singular ( $this -> name ) . '_translations';
  208. return $this -> wrapTableName ( $table );
  209. }
  210. /**
  211. * Get the primary key name, if available
  212. * @param mixed $default
  213. * @return string
  214. */
  215. public function primaryKey ( $default = false )
  216. {
  217. return $this -> get ( 'storage.key', $default );
  218. }
  219. /**
  220. * Get the fields list
  221. * @return array
  222. */
  223. public function fields ()
  224. {
  225. return $this -> get ( 'fields', [] );
  226. }
  227. /**
  228. * Prepend a field to the model definition
  229. * @param string $name
  230. * @param array $config
  231. * @param boolean $overwrite
  232. */
  233. public function prependField ( $name, $config, $overwrite = false )
  234. {
  235. $fields = $this -> fields ();
  236. if ( ! isset ( $fields [ $name ] ) or $overwrite )
  237. {
  238. $newFields = [ $name => $config ];
  239. foreach ( $fields as $name => $config )
  240. {
  241. $newFields [ $name ] = $config;
  242. }
  243. $this -> data [ 'fields' ] = $newFields;
  244. }
  245. }
  246. /**
  247. * Append a field to the model definition
  248. * @param string $name
  249. * @param array $config
  250. * @param boolean $overwrite
  251. */
  252. public function appendField ( $name, $config, $overwrite = false )
  253. {
  254. $fields = $this -> fields ();
  255. if ( ! isset ( $fields [ $name ] ) or $overwrite )
  256. {
  257. $fields [ $name ] = $config;
  258. $this -> data [ 'fields' ] = $fields;
  259. }
  260. }
  261. /**
  262. * Check if the model has at least a translatable field
  263. * @return boolean
  264. */
  265. public function hasTranslatableFields ()
  266. {
  267. foreach ( $this -> fields () as $field )
  268. {
  269. if ( Arr::get ( $field, 'translatable', false ) )
  270. {
  271. return true;
  272. }
  273. }
  274. return false;
  275. }
  276. /**
  277. * @param mixed $default
  278. * @return string
  279. */
  280. public function getCustomModel ($default = null )
  281. {
  282. if ( $this -> hasTranslatableFields () )
  283. {
  284. $default = 'TranslatableFields';
  285. }
  286. return $this -> get ( 'system.model', $default );
  287. }
  288. /**
  289. * Get the icon name, if available
  290. * @param mixed $default
  291. * @return string
  292. */
  293. public function icon ( $default = false )
  294. {
  295. return $this -> get ( 'display.icon', $default );
  296. }
  297. /**
  298. * Get the plural name if available or try to generate it
  299. * @return string
  300. */
  301. public function plural ()
  302. {
  303. $default = Str :: title ( Str :: plural ( $this -> name ) );
  304. $default = str_replace ( '_', ' ', $default );
  305. return trans ( $this -> get ( 'display.plural', $default ) );
  306. }
  307. /**
  308. * Get the singular name if available or try to generate it
  309. * @return string
  310. */
  311. public function singular ()
  312. {
  313. $default = Str :: title ( Str :: singular ( $this -> name ) );
  314. $default = str_replace ( '_', ' ', $default );
  315. return trans ( $this -> get ( 'display.singular', $default ) );
  316. }
  317. /**
  318. * Merge the given data with the current definition
  319. * @param array $data
  320. * @param boolean $overwrite
  321. * @return \Finnegan\Definitions\Definition
  322. */
  323. protected function merge ( array $data, $overwrite = false )
  324. {
  325. unset ( $data [ 'type' ] );
  326. $this->data = Merger::merge ( $this->data, $data, $overwrite );
  327. }
  328. /**
  329. * @return bool
  330. */
  331. public function sortable ()
  332. {
  333. return $this -> hasComponent ( 'sortable' );
  334. }
  335. /**
  336. * @param string $default
  337. * @return bool|string
  338. */
  339. public function sortablePriorityField ( $default = 'priority' )
  340. {
  341. if ( $sortable = $this -> get ( 'system.sortable' ) )
  342. {
  343. return is_array ( $sortable ) ? Arr::get ( $sortable, 'field', $default ) : $default;
  344. }
  345. return false;
  346. }
  347. public function getStorageFilePath ()
  348. {
  349. $path = $this->get ( 'storage.file' );
  350. if ( is_array ( $path ) )
  351. {
  352. $path = Arr::get ( $path, 'path' );
  353. }
  354. return $path ?: "finnegan/{$this->name}.json";
  355. }
  356. }