manage community repository as a source
This commit is contained in:
parent
05e0462a9a
commit
b91c2f5f76
2 changed files with 411 additions and 38 deletions
|
|
@ -76,18 +76,27 @@ $action = GETPOST('action', 'aZ09');
|
|||
$value = GETPOST('value', 'alpha');
|
||||
$page_y = GETPOSTINT('page_y');
|
||||
$search_keyword = GETPOST('search_keyword', 'alpha');
|
||||
$search_source_dolistore = GETPOSTINT('search_source_dolistore');
|
||||
$search_source_github = GETPOSTINT('search_source_github');
|
||||
$search_status = GETPOST('search_status', 'alpha');
|
||||
$search_nature = GETPOST('search_nature', 'alpha');
|
||||
$search_version = GETPOST('search_version', 'alpha');
|
||||
|
||||
|
||||
// For remotestore search
|
||||
$options = array();
|
||||
$options['per_page'] = 10;
|
||||
$options['no_page'] = ((int) GETPOSTINT('no_page') ? GETPOSTINT('no_page') : 1);
|
||||
$options['categorie'] = ((int) (GETPOSTINT('categorie') ? GETPOSTINT('categorie') : 0));
|
||||
$options['search'] = GETPOST('search_keyword', 'alpha');
|
||||
$options['source'] = GETPOST('source', 'alpha');
|
||||
$options = array();
|
||||
$options['per_page'] = 10;
|
||||
$options['no_page'] = ((int) GETPOSTINT('no_page') ? GETPOSTINT('no_page') : 1);
|
||||
$options['categorie'] = ((int) (GETPOSTINT('categorie') ? GETPOSTINT('categorie') : 0));
|
||||
$options['search'] = GETPOST('search_keyword', 'alpha');
|
||||
$options['search_source_dolistore'] = GETPOSTINT('search_source_dolistore');
|
||||
$options['search_source_github'] = GETPOSTINT('search_source_github');
|
||||
|
||||
// Set default values
|
||||
if (empty($options['search_source_dolistore']) && empty($options['search_source_github'])) {
|
||||
$options['search_source_dolistore'] = 1;
|
||||
$options['search_source_github'] = 1;
|
||||
}
|
||||
|
||||
//$remotestore = new Dolistore(false);
|
||||
$remotestore = new ExternalModules();
|
||||
|
|
@ -116,6 +125,12 @@ if (!GETPOST('buttonreset', 'alpha')) {
|
|||
if ($search_keyword) {
|
||||
$param .= '&search_keyword='.urlencode($search_keyword);
|
||||
}
|
||||
if ($search_source_dolistore) {
|
||||
$param .= '&search_source_dolistore='.urlencode($search_source_dolistore);
|
||||
}
|
||||
if ($search_source_github) {
|
||||
$param .= '&search_source_github='.urlencode($search_source_github);
|
||||
}
|
||||
if ($search_status && $search_status != '-1') {
|
||||
$param .= '&search_status='.urlencode($search_status);
|
||||
}
|
||||
|
|
@ -175,6 +190,8 @@ if (GETPOST('buttonreset', 'alpha')) {
|
|||
$search_status = '';
|
||||
$search_nature = '';
|
||||
$search_version = '';
|
||||
$search_source_dolistore = '';
|
||||
$search_source_github = '';
|
||||
}
|
||||
|
||||
if ($action == 'install' && $allowonlineinstall) {
|
||||
|
|
@ -1254,6 +1271,7 @@ if ($mode == 'marketplace') {
|
|||
print '<td class="hideonsmartphone">'.$form->textwithpicto($langs->trans("Provider"), $langs->trans("WebSiteDesc")).'</td>';
|
||||
print '<td></td>';
|
||||
print '<td>'.$langs->trans("URL").'</td>';
|
||||
print '<td></td>';
|
||||
print '</tr>';
|
||||
|
||||
// Marketplace
|
||||
|
|
@ -1262,6 +1280,7 @@ if ($mode == 'marketplace') {
|
|||
print '<td class="hideonsmartphone"><a href="'.$url.'" target="_blank" rel="noopener noreferrer external"><img border="0" class="imgautosize imgmaxwidth180" src="'.DOL_URL_ROOT.'/theme/dolistore_logo.png"></a></td>';
|
||||
print '<td><span class="opacitymedium">'.$langs->trans("DoliStoreDesc").'</span></td>';
|
||||
print '<td><a href="'.$url.'" target="_blank" rel="noopener noreferrer external">'.$url.'</a></td>';
|
||||
print '<td>' . $remotestore->libStatut($remotestore->dolistoreApiStatus).'</td>';
|
||||
print '</tr>';
|
||||
|
||||
// Community
|
||||
|
|
@ -1270,6 +1289,7 @@ if ($mode == 'marketplace') {
|
|||
print '<td class="hideonsmartphone"><a href="'.$url.'" target="_blank" rel="noopener noreferrer external"><img border="0" class="imgautosize imgmaxwidth180" src="'.DOL_URL_ROOT.'/theme/dolibarr_logo.png"></a></td>';
|
||||
print '<td><span class="opacitymedium">'.$langs->trans("CommunityModulesDesc").'</span></td>';
|
||||
print '<td><a href="'.$url.'" target="_blank" rel="noopener noreferrer external">'.$url.'</a></td>';
|
||||
print '<td>' . $remotestore->libStatut($remotestore->githubFileStatus) . '</td>';
|
||||
print '</tr>';
|
||||
|
||||
print "</table>\n";
|
||||
|
|
@ -1279,9 +1299,9 @@ if ($mode == 'marketplace') {
|
|||
|
||||
print '<br>';
|
||||
|
||||
$conf->global->MAIN_DISABLE_DOLISTORE_SEARCH = 1; // avoid warning with the new Dolistore website
|
||||
$conf->global->MAIN_DISABLE_DOLISTORE_SEARCH = 0; // avoid warning with the new Dolistore website
|
||||
|
||||
if (!getDolGlobalString('MAIN_DISABLE_DOLISTORE_SEARCH') && getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2) {
|
||||
if (!getDolGlobalString('MAIN_DISABLE_DOLISTORE_SEARCH') && getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2 && $remotestore->numberOfProviders > 0) {
|
||||
// $options is array with filter criteria
|
||||
|
||||
if (getDolGlobalInt('MAIN_ENANLE_OLD_DOLISTORE')) {
|
||||
|
|
@ -1308,12 +1328,23 @@ if ($mode == 'marketplace') {
|
|||
<input type="hidden" name="mode" value="marketplace">
|
||||
<div class="divsearchfield">
|
||||
<input name="search_keyword" placeholder="<?php echo $langs->trans('Keyword') ?>" id="search_keyword" type="text" class="minwidth200" value="<?php echo dol_escape_htmltag($options['search']) ?>">
|
||||
<!-- Add a check box to filter by source -->
|
||||
<!-- <input type="checkbox" name="search_source" id="search_source_dolistore" value="dolistore" <?php if ($options['source'] == 'dolistore') { echo 'checked'; } ?>>
|
||||
<label for="search_source_dolistore"><?php echo "Dolistore"; ?></label>
|
||||
<input type="checkbox" name="search_source" id="search_source_github" value="github" <?php if ($options['source'] == 'github') { echo 'checked'; } ?>>
|
||||
<label for="search_source_github"><?php echo "Github"; ?></label> -->
|
||||
<br>
|
||||
<!-- Add a check box to filter by source -->
|
||||
<?php
|
||||
$checkAllSources = 0;
|
||||
if (empty($search_source_dolistore) && empty($search_source_github)) {
|
||||
$checkAllSources = 1;
|
||||
}
|
||||
?>
|
||||
<?php if ($remotestore->dolistoreApiStatus > 0 && $remotestore->numberOfProviders > 1) : ?>
|
||||
<input type="checkbox" name="search_source_dolistore" id="search_source_dolistore" value="1" <?php if (!empty($search_source_dolistore) || $checkAllSources == 1) { echo 'checked'; } ?>>
|
||||
<label for="search_source_dolistore"><?php echo "Dolistore"; ?></label>
|
||||
<?php endif ?>
|
||||
|
||||
<?php if ($remotestore->githubFileStatus > 0 && $remotestore->numberOfProviders > 1) : ?>
|
||||
<input type="checkbox" name="search_source_github" id="search_source_github" value="1" <?php if (!empty($search_source_github) || $checkAllSources == 1) echo 'checked'; ?>>
|
||||
<label for="search_source_github"><?php print $langs->trans("communityRepo"); ?></label>
|
||||
<?php endif ?>
|
||||
|
||||
|
||||
</div>
|
||||
<div class="divsearchfield">
|
||||
|
|
@ -1330,15 +1361,16 @@ if ($mode == 'marketplace') {
|
|||
print '</div></div>';
|
||||
print '<div class="clearboth"></div>';
|
||||
?>
|
||||
<?php if (!empty($categories_tree)) { ?>
|
||||
<div id="category-tree-left">
|
||||
<ul class="tree">
|
||||
<?php
|
||||
print $categories_tree; ?>
|
||||
</ul>
|
||||
</div>
|
||||
<?php } ?>
|
||||
|
||||
<div id="category-tree-left">
|
||||
<ul class="tree">
|
||||
<?php
|
||||
print $categories_tree; ?>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div id="listing-content">
|
||||
<div id="listing-content" <?php if (empty($categories_tree)) { ?>style="width:100%;"<?php } ?>>
|
||||
<table summary="list_of_modules" id="list_of_modules" class="productlist centpercent">
|
||||
<tbody id="listOfModules">
|
||||
<?php //echo $remotestore->get_products($nbmaxtoshow); ?>
|
||||
|
|
|
|||
|
|
@ -46,6 +46,17 @@ class ExternalModules
|
|||
/**
|
||||
* @var string
|
||||
*/
|
||||
|
||||
/**
|
||||
* @var string GitHub YAML file URL
|
||||
*/
|
||||
public $file_source_url;
|
||||
|
||||
/**
|
||||
* @var string Cache file path for GitHub modules YAML file content (local)
|
||||
*/
|
||||
public $cache_file;
|
||||
|
||||
public $url; // the url of this page
|
||||
/**
|
||||
* @var string
|
||||
|
|
@ -68,6 +79,26 @@ class ExternalModules
|
|||
*/
|
||||
public $dolistore_api_key;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public $dolistoreApiStatus;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $dolistoreApiError;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public $githubFileStatus;
|
||||
|
||||
/**
|
||||
* @var int // number of online providers
|
||||
*/
|
||||
public $numberOfProviders;
|
||||
|
||||
/**
|
||||
* @var array<int, mixed>|null
|
||||
*/
|
||||
|
|
@ -89,6 +120,10 @@ class ExternalModules
|
|||
$this->shop_url = 'https://www.dolistore.com/product.php?id=';
|
||||
$this->debug_api = $debug;
|
||||
|
||||
$this->file_source_url = "https://raw.githubusercontent.com/Dolibarr/dolibarr-community-modules/refs/heads/main/index.yaml";
|
||||
$this->cache_file = DOL_DOCUMENT_ROOT.'/admin/remotestore/sources/github_modules_file.yaml';
|
||||
$this->getRemoteYamlFile($this->file_source_url, 86400);
|
||||
|
||||
$lang = $langs->defaultlang;
|
||||
$lang_array = array('en_US', 'fr_FR', 'es_ES', 'it_IT', 'de_DE');
|
||||
if (!in_array($lang, $lang_array)) {
|
||||
|
|
@ -96,7 +131,12 @@ class ExternalModules
|
|||
}
|
||||
$this->lang = $lang;
|
||||
|
||||
// TODO check access to all remote sources and define valid one
|
||||
// Check access to Dolistore API
|
||||
$this->dolistoreApiStatus = $this->checkApiStatus();
|
||||
$this->githubFileStatus = file_exists($this->cache_file);
|
||||
|
||||
// Count the number of online providers
|
||||
$this->numberOfProviders = $this->dolistoreApiStatus + $this->githubFileStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -105,7 +145,7 @@ class ExternalModules
|
|||
* @param string $resource Resource name
|
||||
* @param array<string, mixed>|false $options Options for the request
|
||||
*
|
||||
* @return array{status_code:int,response:?string,header:string}
|
||||
* @return array{status_code:int,response:null|string|array<string,mixed>,header:string}
|
||||
*/
|
||||
public function callApi($resource, $options = false)
|
||||
{
|
||||
|
|
@ -139,6 +179,8 @@ class ExternalModules
|
|||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($curl, CURLOPT_HTTPHEADER, $httpheader);
|
||||
curl_setopt($curl, CURLOPT_HEADER, true);
|
||||
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
|
||||
|
||||
$response = curl_exec($curl);
|
||||
|
||||
|
|
@ -161,6 +203,30 @@ class ExternalModules
|
|||
return array('status_code' => $status_code, 'response' => $body, 'header' => $header);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch modules from a cache YAML file
|
||||
* @param array<string, mixed> $options Options for filter
|
||||
*
|
||||
* @return array<string, mixed> List of modules
|
||||
*/
|
||||
public function fetchModulesFromFile($options = array())
|
||||
{
|
||||
$modules = array();
|
||||
|
||||
if (!empty($this->cache_file) && file_exists($this->cache_file)) {
|
||||
dol_syslog(__METHOD__ . " - Loading cache file: " . $this->cache_file, LOG_DEBUG);
|
||||
|
||||
$content = file_get_contents($this->cache_file);
|
||||
if ($content !== false) {
|
||||
$modules = $this->readYaml($content);
|
||||
} else {
|
||||
dol_syslog(__METHOD__ . " - Error reading cache file", LOG_ERR);
|
||||
}
|
||||
}
|
||||
|
||||
return $modules;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate HTML for categories and their children.
|
||||
*
|
||||
|
|
@ -182,8 +248,6 @@ class ExternalModules
|
|||
return $html ;
|
||||
}
|
||||
|
||||
// TODO call all sources and merge them
|
||||
|
||||
$html = '';
|
||||
foreach ($organized_tree as $key => $value) {
|
||||
if ($value['label'] != "Versions" && $value['label'] != "Specials") {
|
||||
|
|
@ -215,12 +279,9 @@ class ExternalModules
|
|||
|
||||
global $langs;
|
||||
|
||||
// TODO call all sources and merge them
|
||||
|
||||
$html = "";
|
||||
$last_month = dol_now() - (30 * 24 * 60 * 60);
|
||||
$dolibarrversiontouse = DOL_VERSION;
|
||||
$urldolibarrmodules = 'https://www.dolistore.com';
|
||||
|
||||
$this->products = array();
|
||||
|
||||
|
|
@ -237,14 +298,32 @@ class ExternalModules
|
|||
'lang' => $this->lang
|
||||
];
|
||||
|
||||
$resProducts = $this->callApi('products', $data);
|
||||
if (!isset($resProducts['response']) || !is_array($resProducts['response']) || ($resProducts['status_code'] != 200 && $resProducts['status_code'] != 201)) {
|
||||
$html = $this->checkStatusCode($resProducts);
|
||||
|
||||
return $html;
|
||||
// Fetch the products from Dolistore source
|
||||
$dolistoreProducts = array();
|
||||
if ($this->dolistoreApiStatus > 0 && $options['search_source_dolistore'] == 1) {
|
||||
$getDolistoreProducts = $this->callApi('products', $data);
|
||||
if (!isset($getDolistoreProducts['response']) || !is_array($getDolistoreProducts['response']) || ($getDolistoreProducts['status_code'] != 200 && $getDolistoreProducts['status_code'] != 201)) {
|
||||
$dolistoreProducts = array();
|
||||
} else {
|
||||
$dolistoreProducts = $this->adaptData($getDolistoreProducts['response'], 'dolistore');
|
||||
}
|
||||
}
|
||||
|
||||
$this->products = $resProducts['response'];
|
||||
// fetch from github repo
|
||||
$fileProducts = array();
|
||||
if (!empty($this->githubFileStatus) && $options['search_source_github'] == 1) {
|
||||
$fileProducts = $this->fetchModulesFromFile($data);
|
||||
$fileProducts = $this->adaptData($fileProducts, 'github');
|
||||
$fileProducts = $this->applyFilters($fileProducts, $data);
|
||||
}
|
||||
|
||||
// merge both sources
|
||||
$this->products = array_merge($dolistoreProducts, $fileProducts);
|
||||
|
||||
// Sort products list by datec
|
||||
usort($this->products, function ($a, $b) {
|
||||
return strtotime($b['datec'] ?? '0') - strtotime($a['datec'] ?? '0');
|
||||
});
|
||||
|
||||
$i = 0;
|
||||
foreach ($this->products as $product) {
|
||||
|
|
@ -274,9 +353,17 @@ class ExternalModules
|
|||
$price = '<h3>'.price(price2num($product["price_ttc"], 'MT'), 0, $langs, 1, -1, -1, 'EUR').' '.$langs->trans("TTC").'</h3>';
|
||||
$download_link = '<a target="_blank" href="'.$this->shop_url.urlencode($product['id']).'"><img width="32" src="'.DOL_URL_ROOT.'/admin/remotestore/img/follow.png" /></a>';
|
||||
} else {
|
||||
$download_link = '#';
|
||||
$price = '<h3>'.$langs->trans('Free').'</h3>';
|
||||
$download_link = '<a class="paddingleft paddingright" target="_blank" href="'.$this->shop_url.urlencode($product["id"]).'"><img width="32" src="'.DOL_URL_ROOT.'/admin/remotestore/img/follow.png" /></a>';
|
||||
$download_link .= '<a class="paddingleft paddingright" target="_blank" href="'.$urldolibarrmodules.$product["download_link"].'" rel="noopener noreferrer"><img width="32" src="'.DOL_URL_ROOT.'/admin/remotestore/img/Download-128.png" /></a>';
|
||||
if ($product['source'] === 'Dolistore') {
|
||||
$download_link = '<a class="paddingleft paddingright" target="_blank" href="'.$this->shop_url.urlencode($product["id"]).'"><img width="32" src="'.DOL_URL_ROOT.'/admin/remotestore/img/follow.png" /></a>';
|
||||
$download_link .= '<a class="paddingleft paddingright" target="_blank" href="'.$product["download_link"].'" rel="noopener noreferrer"><img width="32" src="'.DOL_URL_ROOT.'/admin/remotestore/img/Download-128.png" /></a>';
|
||||
}
|
||||
|
||||
if ($product['source'] === 'Github') {
|
||||
$download_link = '<a class="paddingleft paddingright" target="_blank" href="'.$product["link"].'"><img width="32" src="'.DOL_URL_ROOT.'/admin/remotestore/img/follow.png" /></a>';
|
||||
$download_link .= '<a class="paddingleft paddingright" target="_blank" href="'.$product["link"].'" rel="noopener noreferrer"><img width="32" src="'.DOL_URL_ROOT.'/admin/remotestore/img/Download-128.png" /></a>';
|
||||
}
|
||||
}
|
||||
|
||||
// Set and check version
|
||||
|
|
@ -322,7 +409,8 @@ class ExternalModules
|
|||
$html .= '<br><small>';
|
||||
$html .= $version; // No dol_escape_htmltag, it is already escape html
|
||||
$html .= '</small></h2>';
|
||||
$html .= '<small> '.dol_print_date(dol_stringtotime($product['tms']), 'dayhour').' - '.$langs->trans('Ref').': '.dol_escape_htmltag($product["ref"]).' - '.dol_escape_htmltag($langs->trans('Id')).': '.((int) $product["id"]).'</small><br>';
|
||||
$html .= '<small> '.dol_print_date(dol_stringtotime($product['tms']), 'day').' - '.$langs->trans('Ref').': '.dol_escape_htmltag($product["ref"]).' - '.dol_escape_htmltag($langs->trans('Id')).': '.((int) $product["id"]).'</small><br>';
|
||||
$html .= '<small>'.$langs->trans('Source').': '.$product["source"].'</small><br>';
|
||||
$html .= '<br>'.dol_escape_htmltag(dol_string_nohtmltag($product["description"]));
|
||||
$html.= '</td>';
|
||||
// do not load if display none
|
||||
|
|
@ -523,4 +611,257 @@ class ExternalModules
|
|||
// Return the formatted error message
|
||||
return sprintf('This call to the API failed and returned an HTTP status of %d. That means: %s.', $request['status_code'], $error_message);
|
||||
}
|
||||
|
||||
/**
|
||||
* get YAML file from remote source and put it in cache file for one day
|
||||
* @param string $file_source_url URL of the remote source
|
||||
* @param string $cache_time Cache time
|
||||
*
|
||||
* @return string Uri of the cache file
|
||||
*/
|
||||
public function getRemoteYamlFile($file_source_url, $cache_time)
|
||||
{
|
||||
$cache_file = $this->cache_file;
|
||||
|
||||
// Check if cache directory exists
|
||||
if (!file_exists(dirname($cache_file))) {
|
||||
mkdir(dirname($cache_file), 0777, true);
|
||||
}
|
||||
|
||||
if (!file_exists($cache_file) || filemtime($cache_file) < dol_now() - $cache_time) {
|
||||
$yaml = file_get_contents($file_source_url);
|
||||
if (!empty($yaml)) {
|
||||
file_put_contents($cache_file, $yaml);
|
||||
}
|
||||
}
|
||||
|
||||
return $cache_file;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Read a YAML string and convert it to an array
|
||||
* @param string $yaml YAML string
|
||||
* @return array<string, mixed> Parsed array representation
|
||||
*/
|
||||
public function readYaml($yaml)
|
||||
{
|
||||
$data = [];
|
||||
$currentPackage = null;
|
||||
$currentSection = null;
|
||||
|
||||
foreach (explode("\n", trim($yaml)) as $line) {
|
||||
$trimmedLine = trim($line);
|
||||
|
||||
// Ignore empty lines and comments
|
||||
if ($trimmedLine === '' || strpos($trimmedLine, '#') === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Match a new package entry (e.g., "- modulename: 'helloasso'")
|
||||
if (preg_match('/^\s*-\s*modulename:\s*["\']?(.*?)["\']?$/', $trimmedLine, $matches)) {
|
||||
if ($currentPackage !== null) {
|
||||
$data[] = $currentPackage;
|
||||
}
|
||||
$currentPackage = ['modulename' => $matches[1]];
|
||||
$currentSection = null;
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the key doesn't start with fr, en, es, it, de, treat it as a section
|
||||
if (!preg_match('/^\s*(fr|en|es|it|de):\s*["\']?(.*?)["\']?$/', $trimmedLine)) {
|
||||
$currentSection = null;
|
||||
}
|
||||
|
||||
// Match a top-level key-value pair (e.g., "author: 'Dolicloud'")
|
||||
if (preg_match('/^(\w[\w-]*):\s*["\']?(.*?)["\']?$/', $trimmedLine, $matches)) {
|
||||
if ($currentPackage !== null) {
|
||||
if ($currentSection) {
|
||||
// Store in the nested section
|
||||
$currentPackage[$currentSection][$matches[1]] = $matches[2] === '' ? null : $matches[2];
|
||||
} else {
|
||||
// Store as a normal key-value pair
|
||||
$currentPackage[$matches[1]] = $matches[2] === '' ? null : $matches[2];
|
||||
}
|
||||
}
|
||||
|
||||
// Match a nested section (e.g., "label:")
|
||||
if (preg_match('/^\s*(label|description):\s*$/', $trimmedLine, $matches)) {
|
||||
$currentSection = $matches[1];
|
||||
$currentPackage[$currentSection] = []; // Initialize as an empty array for nested sections
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Add the last package if available
|
||||
if ($currentPackage !== null) {
|
||||
$data[] = $currentPackage;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adapter data fetched from github remote source to the expected format
|
||||
* @param array<string, mixed> $data Data fetched from github remote source
|
||||
* @param string $source Source of the data
|
||||
*
|
||||
* @return array<string, mixed> Data adapted to the expected format
|
||||
*/
|
||||
public function adaptData($data, $source)
|
||||
{
|
||||
$adaptedData = [];
|
||||
$urldolibarrmodules = 'https://www.dolistore.com';
|
||||
|
||||
if (!is_array($data) || empty($data) || empty($source)) {
|
||||
return $adaptedData;
|
||||
}
|
||||
|
||||
if ($source === 'github') {
|
||||
foreach ($data as $package) {
|
||||
if (empty($package['modulename'])) {
|
||||
continue;
|
||||
}
|
||||
$adaptedPackage = [
|
||||
'ref' => str_replace(' ', '', $package['author'].'@'.$package['modulename'].'@'.$package['current_version']),
|
||||
'label' => !empty($package['label'][substr($this->lang, 0, 2)])
|
||||
? $package['label'][substr($this->lang, 0, 2)]
|
||||
: (!empty($package['label']['en']) ? $package['label']['en'] : $package['modulename']),
|
||||
'description' => !empty($package['description'][substr($this->lang, 0, 2)])
|
||||
? $package['description'][substr($this->lang, 0, 2)]
|
||||
: (!empty($package['description']['en']) ? $package['description']['en'] : ''),
|
||||
'datec' => !empty($package['created_at'])
|
||||
? date('Y-m-d H:i:s', strtotime($package['created_at']))
|
||||
: '',
|
||||
'tms' => !empty($package['last_updated_at'])
|
||||
? date('Y-m-d H:i:s', strtotime($package['last_updated_at']))
|
||||
: '',
|
||||
'price_ttc' => 0,
|
||||
'dolibarr_min' => !empty($package['dolibarrmin'])
|
||||
? $package['dolibarrmin']
|
||||
: 'unknown',
|
||||
'dolibarr_max' => !empty($package['dolibarrmax'])
|
||||
? $package['dolibarrmax']
|
||||
: 'unknown',
|
||||
'module_version' => !empty($package['current_version'])
|
||||
? $package['current_version']
|
||||
: 'unknown',
|
||||
'cover_photo_url' => !empty($package['cover'])
|
||||
? $package['cover']
|
||||
: '#',
|
||||
'category' => !empty($package['category'])
|
||||
? explode(',', str_replace(' ', '', $package['category']))
|
||||
: array(),
|
||||
'link' => !empty($package['git'])
|
||||
? $package['git']
|
||||
: '#',
|
||||
'source' => 'Github'
|
||||
];
|
||||
|
||||
$adaptedData[] = $adaptedPackage;
|
||||
}
|
||||
}
|
||||
|
||||
if ($source === 'dolistore') {
|
||||
foreach ($data as $package) {
|
||||
$adaptedPackage = [
|
||||
'id' => $package['id'],
|
||||
'ref'=> $package['ref'],
|
||||
'label' => $package['label'],
|
||||
'description' => $package['description'],
|
||||
'datec' => $package['datec'],
|
||||
'tms' => $package['tms'],
|
||||
'price_ttc' => $package['price_ttc'],
|
||||
'dolibarr_min' => $package['dolibarr_min'],
|
||||
'dolibarr_max' => $package['dolibarr_max'],
|
||||
'module_version' => $package['module_version'],
|
||||
'cover_photo_url' => $urldolibarrmodules.$package['cover_photo_url'],
|
||||
'source' => 'Dolistore'
|
||||
];
|
||||
|
||||
$adaptedData[] = $adaptedPackage;
|
||||
}
|
||||
}
|
||||
|
||||
return $adaptedData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply filters to the data
|
||||
* @param array<string, mixed> $data Data to filter
|
||||
* @param array<string, mixed> $options Options for the filter
|
||||
*
|
||||
* @return array<string, mixed> Filtered data
|
||||
*/
|
||||
public function applyFilters($data, $options)
|
||||
{
|
||||
$filteredData = $data;
|
||||
|
||||
// Sort products list by datec
|
||||
usort($filteredData, function ($a, $b) {
|
||||
return strtotime($b['datec'] ?? '0') - strtotime($a['datec'] ?? '0');
|
||||
});
|
||||
|
||||
if (!empty($options['search'])) {
|
||||
$filteredData = array_filter($filteredData, function ($package) use ($options) {
|
||||
return stripos($package['label'], $options['search']) !== false || stripos($package['description'], $options['search']) !== false;
|
||||
});
|
||||
}
|
||||
|
||||
if (!empty($options['categorieid'])) {
|
||||
$filteredData = array_filter($filteredData, function ($package) use ($options) {
|
||||
return in_array($options['categorieid'], $package['category']);
|
||||
});
|
||||
}
|
||||
|
||||
// Pagination
|
||||
$filteredData = array_values($filteredData);
|
||||
$filteredData = array_slice($filteredData, ($options['page'] - 1) * $options['limit'], $options['limit']);
|
||||
|
||||
return $filteredData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an Dolistore API is up
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function checkApiStatus()
|
||||
{
|
||||
|
||||
$testRequest = $this->callApi('categories');
|
||||
|
||||
if (!isset($testRequest['response']) || !is_array($testRequest['response']) || ($testRequest['status_code'] != 200 && $testRequest['status_code'] != 201)) {
|
||||
$this->dolistoreApiError = $this->checkStatusCode($testRequest);
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the status icon
|
||||
* @param mixed $status Status
|
||||
* @param mixed $mode Mode
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function libStatut($status, $mode = 3)
|
||||
{
|
||||
global $langs;
|
||||
|
||||
$statusType = 'status4';
|
||||
if ($status == 0) {
|
||||
$statusType = 'status6';
|
||||
}
|
||||
|
||||
$labelStatus[0] = $this->dolistoreApiError;
|
||||
$labelStatus[1] = $langs->transnoentitiesnoconv("online");
|
||||
$labelStatusShort[0] = $this->dolistoreApiError;
|
||||
$labelStatusShort[1] = $langs->transnoentitiesnoconv("online");
|
||||
|
||||
return dolGetStatus($labelStatus[$status], $labelStatusShort[$status], '', $statusType, $mode);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue