Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alexandreelise/f03db3117dd47d865f66c34dc6b6adcd to your computer and use it in GitHub Desktop.
Save alexandreelise/f03db3117dd47d865f66c34dc6b6adcd to your computer and use it in GitHub Desktop.
Create an article in Joomla from streamed csv with raw php using Joomla! 4.x Web Services Api
<?php
declare(strict_types=1);
/*
YOUR ATTENTION PLEASE. THE NEW PLACE FOR THIS CODE IS : https://github.com/alexandreelise/j4x-api-examples
*/
/**
*
* @author Alexandre ELISÉ <contact@alexandree.io>
* @copyright (c) 2009 - present. Alexandre ELISÉ. All rights reserved.
* @license GPL-2.0-and-later GNU General Public License v2.0 or later
* @link https://alexandree.io
*/
// Public url of the sample csv used in this example (CHANGE WITH YOUR OWN CSV URL IF YOU WISH)
$csvUrl = 'https://docs.google.com/spreadsheets/d/e/2PACX-1vTO8DC8xzEEyP754B0kBu1sa2P9Rn3I8OLmq_RJYHwOwTlY8OGvpjp1yvaE84Imj0HYQeJcNKT2TOFR/pub?gid=168068017&single=true&output=csv';
// Your Joomla! 4.x website base url
$baseUrl = 'https://example.org';
$basePath = 'api/index.php/v1';
$endpoint = sprintf('%s/%s/%s', $baseUrl, $basePath, 'content/articles');
$timeout = 10;
// Your Joomla! 4.x Api Token (DO NOT STORE IT IN YOUR REPO USE A VAULT OR A PASSWORD MANAGER)
$token = '';
// PHP Generator to efficiently read the csv file
$generator = function (string $url, array $keys = []): Generator {
if (empty($url))
{
yield new RuntimeException('Url MUST NOT be empty', 422);
}
$defaultKeys = [
'title',
'alias',
'catid',
'articletext',
'language',
'metadesc',
'metakey',
'state',
'featured',
];
$mergedKeys = array_unique(array_merge($defaultKeys, $keys));
$resource = fopen($url, 'r');
if ($resource === false)
{
yield new RuntimeException('Could not read csv file', 500);
}
try
{
//NON-BLOCKING I/O (Does not wait before processing next line.)
stream_set_blocking($resource, false);
do
{
$currentLine = stream_get_line(
$resource,
0,
"\r\n"
);
if (empty($currentLine))
{
yield new RuntimeException('Current line MUST NOT be empty', 422);
}
$extractedContent = str_getcsv($currentLine);
array_shift($extractedContent);
if ($mergedKeys != $extractedContent)
{
$encodedContent = json_encode(array_combine($mergedKeys, $extractedContent));
yield $encodedContent;
}
yield new RuntimeException('Current line seem to be invalid', 422);
} while (!feof($resource));
} finally
{
fclose($resource);
}
};
// Read CSV in a PHP Generator using streams in non-blocking I/O mode
$streamCsv = $generator($csvUrl);
// Process data returned by the PHP Generator
$process = function ($endpoint, $dataString, $headers, $timeout, $transport) {
curl_setopt_array($transport, [
CURLOPT_URL => $endpoint,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => 'utf-8',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => $timeout,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_2TLS,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => $dataString,
CURLOPT_HTTPHEADER => $headers,
]
);
return curl_exec($transport);
};
foreach ($streamCsv as $dataString)
{
if (!is_string($dataString))
{
continue;
}
$curl = curl_init();
try
{
// HTTP request headers
$headers = [
'Accept: application/vnd.api+json',
'Content-Type: application/json',
'Content-Length: ' . mb_strlen($dataString),
sprintf('X-Joomla-Token: %s', trim($token)),
];
$output = $process($endpoint, $dataString, $headers, $timeout, $curl);
// Continue even on partial failure
if ($output === false || array_key_exists('errors', json_decode($output, true)))
{
continue;
}
}
catch (Throwable $e)
{
echo $e->getMessage() . PHP_EOL;
continue;
} finally
{
curl_close($curl);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment