PageRenderTime 45ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/bitrix/modules/mobileapp/lib/designer/manager.php

https://bitbucket.org/alex_poluektov/itech_test
PHP | 532 lines | 335 code | 70 blank | 127 comment | 39 complexity | ddea6c9923c4d3a2bab8ace2f4edbc85 MD5 | raw file
Possible License(s): Apache-2.0
  1. <?php
  2. namespace Bitrix\MobileApp\Designer;
  3. use Bitrix\Main\Application;
  4. use Bitrix\Main\Entity\FieldError;
  5. use Bitrix\Main\IO\Directory;
  6. use Bitrix\Main\IO\File;
  7. use Bitrix\Main\Text\Encoding;
  8. class Manager
  9. {
  10. const IS_ALREADY_EXISTS = 3;
  11. const SUCCESS = 1;
  12. const FAIL = 0;
  13. const EMPTY_REQUIRED = 4;
  14. const APP_TEMPLATE_IS_NOT_EXISTS = 5;
  15. const PREVIEW_IMAGE_SIZE = 150;
  16. const SIMPLE_APP_TEMPLATE = "simple";
  17. /**
  18. * Creates a new application with "global" configuration by default
  19. *
  20. * @param string $appCode - application code
  21. * @param array $data - application data (name, short name, folder and etc)
  22. * @param array $initConfig
  23. *
  24. * @return int
  25. * @throws \Exception
  26. * @see AppTable::getMap to get a bit more information about possible keys in $data
  27. */
  28. public static function createApp($appCode = "", $data = array(), $initConfig = array())
  29. {
  30. $result = self::SUCCESS;
  31. $fields = $data;
  32. $fields["CODE"] = $appCode;
  33. $dbResult = AppTable::add($fields);
  34. if (!$dbResult->isSuccess())
  35. {
  36. $errors = $dbResult->getErrors();
  37. if ($errors[0]->getCode() == FieldError::INVALID_VALUE)
  38. {
  39. $result = self::IS_ALREADY_EXISTS;
  40. }
  41. elseif ($errors[0]->getCode() == FieldError::EMPTY_REQUIRED)
  42. {
  43. $result = self::EMPTY_REQUIRED;
  44. }
  45. }
  46. else
  47. {
  48. self::addConfig($appCode, "global", $initConfig);
  49. }
  50. return $result;
  51. }
  52. private static function getTemplateList()
  53. {
  54. return array(
  55. "simple",
  56. "api"
  57. );
  58. }
  59. /**
  60. * Removes application by code
  61. *
  62. * @param string $appCode application code
  63. *
  64. * @return bool
  65. */
  66. public static function removeApp($appCode)
  67. {
  68. $result = AppTable::delete($appCode);
  69. return $result->isSuccess();
  70. }
  71. /**
  72. * Binds file to the application
  73. *
  74. * @param $fileArray - file array
  75. * @param $appCode - application code
  76. */
  77. public static function registerFileInApp(&$fileArray, $appCode)
  78. {
  79. $result = AppTable::getById($appCode);
  80. $appData = $result->fetchAll();
  81. if (count($appData) > 0)
  82. {
  83. $appData[0]["FILES"][] = $fileArray["fileID"];
  84. AppTable::update($appCode, array("FILES" => $appData[0]["FILES"]));
  85. $arImage = \CFile::ResizeImageGet(
  86. $fileArray["fileID"],
  87. array("width" => self::PREVIEW_IMAGE_SIZE, "height" => self::PREVIEW_IMAGE_SIZE),
  88. BX_RESIZE_IMAGE_EXACT,
  89. false,
  90. false,
  91. true
  92. );
  93. $fileArray["img_source_src"] = $arImage["src"];
  94. }
  95. }
  96. /**
  97. * Unbinds file
  98. *
  99. * @param $fileId - identifier of file in b_file table
  100. * @param $appCode - application code
  101. */
  102. public static function unregisterFileInApp($fileId, $appCode)
  103. {
  104. $result = AppTable::getById($appCode);
  105. $appData = $result->fetchAll();
  106. if (count($appData) > 0)
  107. {
  108. $index = array_search($fileId, $appData[0]["FILES"]);
  109. if ($index !== false)
  110. {
  111. unset($appData[0]["FILES"][$index]);
  112. AppTable::update($appCode, array("FILES" => $appData[0]["FILES"]));
  113. }
  114. die();
  115. }
  116. }
  117. /**
  118. * Add configuration to application
  119. *
  120. * @param string $appCode - application code
  121. * @param $platform - platform code
  122. *
  123. * @see ConfigTable::getSupportedPlatforms for details on availible platforms
  124. *
  125. * @param array $config - configuration
  126. *
  127. * @return bool
  128. */
  129. public static function addConfig($appCode = "", $platform, $config = array())
  130. {
  131. if (ConfigTable::isExists($appCode, $platform))
  132. {
  133. return false;
  134. }
  135. $fields = array(
  136. "APP_CODE" => $appCode,
  137. "PLATFORM" => $platform,
  138. "PARAMS" => $config
  139. );
  140. $result = ConfigTable::add($fields);
  141. return $result->isSuccess();
  142. }
  143. /**
  144. * Removes configuration
  145. *
  146. * @param string $appCode - application code
  147. * @param array $platform - platform code
  148. *
  149. * @see ConfigTable::getSupportedPlatforms for details on availible platforms
  150. * @return bool
  151. */
  152. public static function removeConfig($appCode = "", $platform = array())
  153. {
  154. $filter = array(
  155. "APP_CODE" => $appCode,
  156. "PLATFORM" => $platform,
  157. );
  158. $result = ConfigTable::delete($filter);
  159. return $result->isSuccess();
  160. }
  161. /**
  162. * Updates configuration
  163. *
  164. * @param string $appCode application code
  165. * @param array $platform platform code
  166. * @param array $config new configuration
  167. *
  168. * @see ConfigTable::getSupportedPlatforms
  169. *
  170. * @return bool
  171. */
  172. public static function updateConfig($appCode = "", $platform = "", $config = array())
  173. {
  174. if (!ConfigTable::isExists($appCode, $platform))
  175. {
  176. return false;
  177. }
  178. $map = new ConfigMap();
  179. foreach ($config as $paramName => $value)
  180. {
  181. if (!$map->has($paramName))
  182. {
  183. unset($config[$paramName]);
  184. }
  185. }
  186. $data = array(
  187. "PARAMS" => $config
  188. );
  189. $result = ConfigTable::update(array("APP_CODE" => $appCode, "PLATFORM" => $platform), $data);
  190. return $result->isSuccess();
  191. }
  192. /**
  193. * Return configuration in JSON format
  194. *
  195. * @param $appCode - application code
  196. * @param bool $platform - platform code
  197. *
  198. * @see ConfigTable::getSupportedPlatforms for details on availible platforms
  199. * @return string
  200. * @throws \Bitrix\Main\ArgumentException
  201. */
  202. public static function getConfigJSON($appCode, $platform = false)
  203. {
  204. $map = new \Bitrix\MobileApp\Designer\ConfigMap();
  205. $res = ConfigTable::getList(array(
  206. "filter" => array(
  207. "APP_CODE" => $appCode,
  208. )
  209. ));
  210. $configs = $res->fetchAll();
  211. $targetConfig = array();
  212. for ($i = 0; $i < count($configs); $i++)
  213. {
  214. if ($configs[$i]["PLATFORM"] == $platform)
  215. {
  216. $targetConfig = $configs[$i];
  217. break;
  218. }
  219. elseif ($configs[$i]["PLATFORM"] == "global")
  220. {
  221. $targetConfig = $configs[$i];
  222. }
  223. }
  224. $params = array_key_exists("PARAMS", $targetConfig) ? $targetConfig["PARAMS"]: array() ;
  225. $imageParamList = $map->getParamsByType(ParameterType::IMAGE);
  226. $imageSetParamList = $map->getParamsByType(ParameterType::IMAGE_SET);
  227. $structuredConfig = array();
  228. foreach ($params as $key => $value)
  229. {
  230. if (!$map->has($key))
  231. {
  232. continue;
  233. }
  234. if (array_key_exists($key, $imageParamList))
  235. {
  236. $imagePath = \CFile::GetPath($value);
  237. if(strlen($imagePath)>0)
  238. $value = $imagePath;
  239. else
  240. continue;
  241. }
  242. if (array_key_exists($key, $imageSetParamList))
  243. {
  244. $tmpValue = array();
  245. foreach ($value as $imageCode => $imageId)
  246. {
  247. $imagePath = \CFile::GetPath($imageId);
  248. if(strlen($imagePath)>0)
  249. $tmpValue[$imageCode] = $imagePath;
  250. else
  251. continue;
  252. }
  253. $value = $tmpValue;
  254. }
  255. $structuredConfig = array_merge_recursive(self::nameSpaceToArray($key, $value), $structuredConfig);
  256. }
  257. if(toUpper(SITE_CHARSET) != "UTF-8")
  258. {
  259. $structuredConfig = Encoding::convertEncodingArray($structuredConfig, SITE_CHARSET, "UTF-8");
  260. }
  261. self::addVirtualParams($structuredConfig, $platform);
  262. return json_encode($structuredConfig);
  263. }
  264. /**
  265. * Checks if the configuration is already exists
  266. *
  267. * @param $folder
  268. * @param $appCode - application code
  269. * @param bool $useOffline
  270. * @param string $templateCode
  271. * @return bool
  272. * @throws \Bitrix\Main\IO\FileNotFoundException
  273. * @see ConfigTable::getSupportedPlatforms for details on availible platforms
  274. */
  275. public static function copyFromTemplate($folder, $appCode, $useOffline = false, $templateCode = "simple")
  276. {
  277. if(!in_array($templateCode, self::getTemplateList()))
  278. {
  279. $templateCode = "simple";
  280. }
  281. $appFolderPath = Application::getDocumentRoot() . "/" . $folder . "/";
  282. $offlineTemplate = Application::getDocumentRoot() . "/bitrix/modules/mobileapp/templates_app/offline/";
  283. $templatePath = Application::getDocumentRoot() . "/bitrix/modules/mobileapp/templates_app/".$templateCode."/";
  284. $directory = new Directory($templatePath);
  285. if($directory->isExists())
  286. {
  287. if (!Directory::isDirectoryExists($appFolderPath))
  288. {
  289. if($useOffline)
  290. {
  291. CopyDirFiles($offlineTemplate, $appFolderPath."/offline");
  292. }
  293. $items = $directory->getChildren();
  294. foreach ($items as $entry)
  295. {
  296. /**
  297. * @var $entry \Bitrix\Main\IO\FileSystemEntry
  298. */
  299. $filePath = $entry->getPath();
  300. $appFilePath = $appFolderPath . $entry->getName();
  301. if($entry instanceof Directory)
  302. {
  303. CopyDirFiles($filePath, $appFolderPath."/".$entry->getName(),true,true);
  304. }
  305. else
  306. {
  307. $file = new File($entry->getPath());
  308. File::putFileContents(
  309. $appFilePath,
  310. str_replace(Array("#folder#", "#code#"), Array($folder, $appCode),$file->getContents())
  311. );
  312. }
  313. }
  314. }
  315. }
  316. }
  317. /**
  318. * Binds (and creates if it's necessary) template to the application folder
  319. *
  320. * @param $templateId - symbolic code of the template
  321. * @param $folder - the application folder
  322. * @param bool $createNew - flag of the necessity of creating a new template
  323. */
  324. public static function bindTemplate($templateId, $folder, $createNew)
  325. {
  326. $arFields = Array("TEMPLATE" => Array());
  327. if ($createNew)
  328. {
  329. CopyDirFiles(
  330. Application::getDocumentRoot() . "/bitrix/modules/mobileapp/templates/default_app/",
  331. Application::getDocumentRoot() . "/bitrix/templates/" . $templateId, True, True
  332. );
  333. File::putFileContents(
  334. Application::getDocumentRoot() . "/bitrix/templates/" . $templateId . "/description.php",
  335. str_replace(Array("#mobile_template_name#"), Array($templateId), File::getFileContents(Application::getDocumentRoot() . "/bitrix/templates/" . $templateId . "/description.php"))
  336. );
  337. $arFields["TEMPLATE"][] = Array(
  338. "SORT" => 1,
  339. "CONDITION" => "CSite::InDir('/" . $folder . "/')",
  340. "TEMPLATE" => $templateId
  341. );
  342. }
  343. $default_site_id = \CSite::GetDefSite();
  344. if ($default_site_id)
  345. {
  346. $dbTemplates = \CSite::GetTemplateList($default_site_id);
  347. $arFields["LID"] = $default_site_id;
  348. $isTemplateFound = false;
  349. while ($template = $dbTemplates->Fetch())
  350. {
  351. $arFields["TEMPLATE"][] = array(
  352. "TEMPLATE" => $template['TEMPLATE'],
  353. "SORT" => $template['SORT'],
  354. "CONDITION" => $template['CONDITION']
  355. );
  356. if ($template["TEMPLATE"] == $templateId && !$createNew && !$isTemplateFound)
  357. {
  358. $isTemplateFound = true;
  359. $arFields["TEMPLATE"][] = Array(
  360. "SORT" => 1,
  361. "CONDITION" => "CSite::InDir('/" . $folder . "/')",
  362. "TEMPLATE" => $templateId
  363. );
  364. }
  365. }
  366. $obSite = new \CSite;
  367. $obSite->Update($default_site_id, $arFields);
  368. }
  369. }
  370. /**
  371. * Return files of the application
  372. * @param $appCode - application code
  373. * @return array
  374. */
  375. public static function getAppFiles($appCode)
  376. {
  377. $result = AppTable::getById($appCode);
  378. $appData = $result->fetchAll();
  379. $files = array();
  380. if (count($appData) > 0)
  381. {
  382. //TODO fix, use module_id in the filter
  383. $result = \CFile::GetList(array("ID" => "desc"), Array("@ID" => implode(",", $appData[0]["FILES"])));
  384. while ($file = $result->Fetch())
  385. {
  386. $image = \CFile::ResizeImageGet(
  387. $file["ID"],
  388. array("width" => self::PREVIEW_IMAGE_SIZE, "height" => self::PREVIEW_IMAGE_SIZE),
  389. BX_RESIZE_IMAGE_EXACT,
  390. false,
  391. false,
  392. true
  393. );
  394. $files["file_" . $file["ID"]] = array(
  395. "id" => $file["ID"],
  396. "src" => \CFile::GetFileSRC($file),
  397. "preview" => $image["src"]
  398. );
  399. }
  400. }
  401. return $files;
  402. }
  403. /**
  404. * Converts the namespace string to the array
  405. * and assigns the given value to the key of deepest level of the namespace
  406. *
  407. * @param $namespace - namespace string
  408. * @param $value - value
  409. *
  410. * <br>
  411. *
  412. * Here is an example:
  413. * <code>
  414. * $namespace = "\depth0\depth1\depth3"
  415. * $value = "value1";
  416. * $resultArray = \Bitrix\MobileApp\Designer\Manager\nameSpaceToArray($namespace,$value));
  417. *
  418. * <b>Result:</b>
  419. * array(
  420. * "depth0"=>array(
  421. * "depth1"=>array(
  422. * "depth2"=>"value1"
  423. * )
  424. * )
  425. *);
  426. *
  427. * </code>
  428. *
  429. * @return array
  430. */
  431. private function nameSpaceToArray($namespace, $value)
  432. {
  433. $keys = explode("/", $namespace);
  434. $result = array();
  435. $temp = & $result;
  436. for ($i = 0; $i < count($keys); $i++)
  437. {
  438. $temp = & $temp[$keys[$i]];
  439. }
  440. $temp = $value;
  441. return $result;
  442. }
  443. private static function addVirtualParams(&$structuredConfig, $platform)
  444. {
  445. if($structuredConfig["offline"] && !empty($structuredConfig["offline"]["file_list"]))
  446. {
  447. $offlineParams = &$structuredConfig["offline"];
  448. $offlineParams["file_list"]["bitrix_mobile_core.js"] = Tools::getMobileJSCorePath();
  449. $changeMark = Tools::getArrayFilesHash($offlineParams["file_list"]);
  450. $offlineParams["change_mark"] = $changeMark;
  451. }
  452. if($structuredConfig["buttons"]["badge"])
  453. {
  454. $structuredConfig["buttons_badge"] = $structuredConfig["buttons"]["badge"];
  455. unset($structuredConfig["buttons"]["badge"]);
  456. }
  457. $structuredConfig["info"] = array(
  458. "designer_version"=> ConfigMap::VERSION,
  459. "platform"=>$platform
  460. );
  461. }
  462. }