|
|
|
<?php
|
|
|
|
|
|
|
|
// Init version
|
|
|
|
define(
|
|
|
|
'_CLITOR_IS_',
|
|
|
|
'1.3.0'
|
|
|
|
);
|
|
|
|
|
|
|
|
// Init helper
|
|
|
|
function _exec(
|
|
|
|
string $processor,
|
|
|
|
string $command
|
|
|
|
): mixed
|
|
|
|
{
|
|
|
|
if (false !== exec(sprintf('%s %s', $processor, $command), $output))
|
|
|
|
{
|
|
|
|
$rows = [];
|
|
|
|
|
|
|
|
foreach($output as $row)
|
|
|
|
{
|
|
|
|
$rows[] = $row;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($result = @json_decode(implode(PHP_EOL, $rows)))
|
|
|
|
{
|
|
|
|
return $result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Validate arguments
|
|
|
|
if (empty($argv[1]))
|
|
|
|
{
|
|
|
|
print(
|
|
|
|
'processor required' . PHP_EOL
|
|
|
|
);
|
|
|
|
|
|
|
|
exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!file_exists($argv[1]))
|
|
|
|
{
|
|
|
|
print(
|
|
|
|
'processor does not exist' . PHP_EOL
|
|
|
|
);
|
|
|
|
|
|
|
|
exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (empty($argv[2]))
|
|
|
|
{
|
|
|
|
print(
|
|
|
|
'namespace required' . PHP_EOL
|
|
|
|
);
|
|
|
|
|
|
|
|
exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (empty($argv[3]))
|
|
|
|
{
|
|
|
|
print(
|
|
|
|
'destination file required' . PHP_EOL
|
|
|
|
);
|
|
|
|
|
|
|
|
exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (file_exists($argv[3]))
|
|
|
|
{
|
|
|
|
print(
|
|
|
|
'destination file already exists' . PHP_EOL
|
|
|
|
);
|
|
|
|
|
|
|
|
exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get clitoris
|
|
|
|
$clitoris = _exec(
|
|
|
|
$argv[1],
|
|
|
|
sprintf(
|
|
|
|
'keva_get %s "_CLITOR_IS_"',
|
|
|
|
$argv[2]
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
// Validate protocol
|
|
|
|
if (empty($clitoris->value))
|
|
|
|
{
|
|
|
|
print(
|
|
|
|
'_CLITOR_IS_ not found' . PHP_EOL
|
|
|
|
);
|
|
|
|
|
|
|
|
exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Merge content data
|
|
|
|
$chain = [];
|
|
|
|
|
|
|
|
foreach (
|
|
|
|
(array)
|
|
|
|
_exec(
|
|
|
|
$argv[1],
|
|
|
|
sprintf(
|
|
|
|
'keva_filter %s "\d+"',
|
|
|
|
$argv[2]
|
|
|
|
)
|
|
|
|
) as $piece)
|
|
|
|
{
|
|
|
|
if (
|
|
|
|
!isset($piece->key) ||
|
|
|
|
!isset($piece->value) ||
|
|
|
|
!isset($piece->height)
|
|
|
|
)
|
|
|
|
{
|
|
|
|
print(
|
|
|
|
'please wait for all pieces sending complete!' . PHP_EOL
|
|
|
|
);
|
|
|
|
|
|
|
|
exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Keep all key versions in memory
|
|
|
|
$chain[$piece->key][$piece->height] = $piece->value;
|
|
|
|
|
|
|
|
print_r(
|
|
|
|
$piece
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Select last piece value by it max block height
|
|
|
|
//
|
|
|
|
// piece could have many of versions (with same key)
|
|
|
|
// this feature related to data reading correction after recovery #1
|
|
|
|
|
|
|
|
$pieces = [];
|
|
|
|
|
|
|
|
foreach ($chain as $key => $height)
|
|
|
|
{
|
|
|
|
ksort(
|
|
|
|
$height
|
|
|
|
);
|
|
|
|
|
|
|
|
$pieces[$key] = $height
|
|
|
|
[
|
|
|
|
array_key_last(
|
|
|
|
$height
|
|
|
|
)
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
ksort(
|
|
|
|
$pieces
|
|
|
|
);
|
|
|
|
|
|
|
|
// Save file to destination
|
|
|
|
file_put_contents(
|
|
|
|
$argv[3],
|
|
|
|
base64_decode(
|
|
|
|
implode('', $pieces)
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
printf(
|
|
|
|
'namespace "%s" saved to "%s"' . PHP_EOL,
|
|
|
|
$argv[2],
|
|
|
|
$argv[3]
|
|
|
|
);
|