Merge pull request #18316 from civicrm/5.29
[civicrm-core.git] / CRM / Core / CodeGen / DAO.php
1 <?php
2
3 /**
4 * Create DAO ORM classes.
5 */
6 class CRM_Core_CodeGen_DAO extends CRM_Core_CodeGen_BaseTask {
7
8 /**
9 * @var string
10 */
11 public $name;
12
13 /**
14 * @var string
15 */
16 private $tableChecksum;
17
18 /**
19 * @var string
20 */
21 private $raw;
22
23 /**
24 * @var string
25 * translate function name
26 */
27 private $tsFunctionName;
28
29 private $useHelper = '';
30
31 private $ext = "'civicrm'";
32
33 /**
34 * CRM_Core_CodeGen_DAO constructor.
35 *
36 * @param \CRM_Core_CodeGen_Main $config
37 * @param string $name
38 * @param string $tsFunctionName
39 */
40 public function __construct($config, $name, $tsFunctionName = 'ts') {
41 parent::__construct($config);
42 $this->name = $name;
43 $this->tsFunctionName = $tsFunctionName;
44 // If this DAO belongs to an extension, add `use` statement and define EXT constant.
45 if (strpos($tsFunctionName, '::ts')) {
46 $this->tsFunctionName = 'E::ts';
47 $this->useHelper = 'use \\' . explode('::', $tsFunctionName)[0] . ' as E;';
48 $this->ext = 'E::LONG_NAME';
49 }
50 }
51
52 /**
53 * @return bool
54 * TRUE if an update is needed.
55 */
56 public function needsUpdate() {
57 if (!file_exists($this->getAbsFileName())) {
58 return TRUE;
59 }
60
61 if ($this->getTableChecksum() !== self::extractRegex($this->getAbsFileName(), ';\(GenCodeChecksum:([a-zA-Z0-9]+)\);')) {
62 return TRUE;
63 }
64
65 return !$this->isApproxPhpMatch(
66 file_get_contents($this->getAbsFileName()),
67 $this->getRaw());
68 }
69
70 /**
71 * Run generator.
72 */
73 public function run() {
74 echo "Generating {$this->name} as " . $this->getRelFileName() . "\n";
75
76 if (empty($this->tables[$this->name]['base'])) {
77 echo "No base defined for {$this->name}, skipping output generation\n";
78 return;
79 }
80
81 $template = $this->getTemplate();
82 $template->assign('genCodeChecksum', $this->getTableChecksum());
83 $template->run('dao.tpl', $this->getAbsFileName());
84 }
85
86 /**
87 * Generate the raw PHP code for the DAO.
88 *
89 * @return string
90 */
91 public function getRaw() {
92 if (!$this->raw) {
93 $template = $this->getTemplate();
94 $template->assign('genCodeChecksum', 'NEW');
95 $this->raw = $template->fetch('dao.tpl');
96 }
97 return $this->raw;
98 }
99
100 /**
101 * @return CRM_Core_CodeGen_Util_Template
102 */
103 private function getTemplate() {
104 $template = new CRM_Core_CodeGen_Util_Template('php');
105 $template->assign('table', $this->tables[$this->name]);
106 if (empty($this->tables[$this->name]['index'])) {
107 $template->assign('indicesPhp', var_export([], 1));
108 }
109 else {
110 $template->assign('indicesPhp', var_export($this->tables[$this->name]['index'], 1));
111 }
112 $template->assign('tsFunctionName', $this->tsFunctionName);
113 $template->assign('ext', $this->ext);
114 $template->assign('useHelper', $this->useHelper);
115 return $template;
116 }
117
118 /**
119 * Get relative file name.
120 *
121 * @return string
122 */
123 public function getRelFileName() {
124 return $this->tables[$this->name]['fileName'];
125 }
126
127 /**
128 * Get the absolute file name.
129 *
130 * @return string
131 */
132 public function getAbsFileName() {
133 $directory = $this->config->phpCodePath . $this->tables[$this->name]['base'];
134 CRM_Core_CodeGen_Util_File::createDir($directory);
135 $absFileName = $directory . $this->getRelFileName();
136 return $absFileName;
137 }
138
139 /**
140 * Get a unique signature for the table/schema.
141 *
142 * @return string
143 */
144 protected function getTableChecksum() {
145 if (!$this->tableChecksum) {
146 $flat = [];
147 CRM_Utils_Array::flatten($this->tables[$this->name], $flat);
148 ksort($flat);
149 $this->tableChecksum = md5(json_encode($flat));
150 }
151 return $this->tableChecksum;
152 }
153
154 }