] #
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%#
# #
# The BigPipe main class is responsible for sorting and rendering the pagelets #
# and their associated resources. This class also provides methods to turn off #
# the pipelining mode or turn on the debugging mode. #
# #
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%#
namespace BigPipe;
class BigPipe {
private static $debugging = FALSE;
private static $enabled = TRUE;
private static $pagelets = [];
private static $count = 0;
#===============================================================================
# Enable or disable the pipeline mode
#===============================================================================
public static function enabled($change = NULL) {
if($change !== NULL) {
self::$enabled = (bool) $change;
}
return self::$enabled;
}
#===============================================================================
# Return if debugging is enabled or change
#===============================================================================
public static function debugging($change = NULL): bool {
if($change !== NULL) {
self::$debugging = (bool) $change;
}
return self::$debugging;
}
#===============================================================================
# Add a new pagelet to pipeline
#===============================================================================
public static function addPagelet(Pagelet $Pagelet, $priority) {
self::$pagelets[$priority][] = $Pagelet;
return ++self::$count;
}
#===============================================================================
# Prints a single pagelet response
#===============================================================================
private static function singleResponse(Pagelet $Pagelet, $last = FALSE) {
if(self::debugging()) {
self::addDebugPhaseDoneJS($Pagelet);
array_map('self::addDebugPhaseDoneJS', $Pagelet->getResources()[Resource::TYPE_STYLESHEET]);
array_map('self::addDebugPhaseDoneJS', $Pagelet->getResources()[Resource::TYPE_JAVASCRIPT]);
usleep(rand(125, 175) * 2000);
}
$stylesheets = [];
$javascripts = [];
foreach($Pagelet->getResources()[Resource::TYPE_STYLESHEET] as $Resource) {
$stylesheets[] = ['ID' => $Resource->getID(), 'HREF' => $Resource->getURL(), 'PHASE' => $Resource->getPhaseDoneJS()];
}
foreach($Pagelet->getResources()[Resource::TYPE_JAVASCRIPT] as $Resource) {
$javascripts[] = ['ID' => $Resource->getID(), 'HREF' => $Resource->getURL(), 'PHASE' => $Resource->getPhaseDoneJS()];
}
$pageletJSON = [
'ID' => $Pagelet->getID(),
'NEED' => $Pagelet->getDependencies(),
'RSRC' => [
Resource::TYPE_STYLESHEET => $stylesheets,
Resource::TYPE_JAVASCRIPT => $javascripts,
],
'CODE' => removeLineBreaksAndTabs($Pagelet->getJSCode()),
'PHASE' => $Pagelet->getPhaseDoneJS()
];
if($last) {
$pageletJSON['IS_LAST'] = TRUE;
}
$pageletHTML = removeLineBreaksAndTabs($Pagelet->getHTML());
$pageletHTML = str_replace('--', '--', $pageletHTML);
$pageletJSON = json_encode($pageletJSON, (self::debugging() ? JSON_PRETTY_PRINT : NULL));
echo "getID()}\">
\n";
echo "\n\n";
}
#===============================================================================
# Sends output buffer so far as possible towards user
#===============================================================================
public static function flushOutputBuffer() {
ob_flush(); flush();
}
#===============================================================================
# Render the pagelets
#===============================================================================
public static function render() {
self::flushOutputBuffer();
$i = 0;
ksort(self::$pagelets);
foreach(array_reverse(self::$pagelets) as $priority => $pagelets) {
foreach($pagelets as $Pagelet) {
if(!self::enabled()) {
foreach($Pagelet->getResources()[Resource::TYPE_STYLESHEET] as $Resource) {
echo $Resource->renderHTML()."\n";
}
foreach($Pagelet->getResources()[Resource::TYPE_JAVASCRIPT] as $Resource) {
echo $Resource->renderHTML()."\n";
}
foreach($Pagelet->getJSCode() as $JSCode) {
echo "\n";
}
}
else {
self::singleResponse($Pagelet, (self::$count === ++$i));
self::flushOutputBuffer();
}
}
}
}
#===============================================================================
# Add PhaseDoneJS for debugging Pagelet and Resource
#===============================================================================
private static function addDebugPhaseDoneJS($Instance) {
$objpath = str_replace('\\', '|', get_class($Instance));
if($Instance instanceof Pagelet) {
$message = "console.log(\"%%c[{$objpath}]%%c#(%%c%s%%c): PhaseDoneJS for phase: %s\", \"font-weight:bold\", \"color:#666\", \"color:#008B45\", \"color:#666\")";
$Instance->addPhaseDoneJS($Instance::PHASE_INIT, sprintf($message, $Instance->getID(), 'INIT'));
$Instance->addPhaseDoneJS($Instance::PHASE_LOADCSS, sprintf($message, $Instance->getID(), 'LOADCSS'));
$Instance->addPhaseDoneJS($Instance::PHASE_HTML, sprintf($message, $Instance->getID(), 'HTML'));
$Instance->addPhaseDoneJS($Instance::PHASE_LOADJS, sprintf($message, $Instance->getID(), 'LOADJS'));
$Instance->addPhaseDoneJS($Instance::PHASE_DONE, sprintf($message, $Instance->getID(), 'DONE'));
return $Instance;
}
if($Instance instanceof Resource) {
$message = "console.log(\"[{$objpath}]%%c#(%%c%s%%c): PhaseDoneJS for phase: %s\", \"color:#666\", \"color:#008B45\", \"color:#666\")";
$Instance->addPhaseDoneJS($Instance::PHASE_INIT, sprintf($message, $Instance->getID(), 'INIT'));
$Instance->addPhaseDoneJS($Instance::PHASE_LOAD, sprintf($message, $Instance->getID(), 'LOAD'));
$Instance->addPhaseDoneJS($Instance::PHASE_DONE, sprintf($message, $Instance->getID(), 'DONE'));
return $Instance;
}
}
}
?>