/** * Renders each section of the footer. * * @return string * The generated markup. */ public function callMe() { $sectionOutput = ''; foreach ($this->parameters['data'] as $name => $setting) { // Render the single value. // We need to find out where the value comes from. $value = $setting->getValue(); if ($setting->getType() != 'None') { // We need to re-translate booleans to something the // frontend can understand. if ($value === true) { $value = 'true'; } if ($value === false) { $value = 'false'; } $model = new Model($this->storage); if ($setting->getEditable()) { $model->setData($name)->setName($value)->setNormal($setting->getSource())->setType($setting->getType())->setHelpid($name); $sectionOutput .= $this->storage->render->renderSingleEditableChild($model); } else { $model->setData($value)->setName($name)->setNormal($value)->setType($setting->getSource())->setHelpid($name); $sectionOutput .= $this->storage->render->renderSingleChild($model); } } } return $sectionOutput; }
/** * Renders whole configuration. * * @return string * The generated markup. */ public function callMe() { $configOutput = ''; // We need to "explode" our config array into the // sections again, for better readability. $sections = array(); foreach ($this->storage->config->settings as $name => $setting) { $sections[$setting->getSection()][$name] = $setting; } foreach ($sections as $sectionName => $sectionData) { // Render a whole section. $model = new Model($this->storage); $model->setName($sectionName)->setType('Config')->setAdditional('. . .')->addParameter('data', $sectionData)->initCallback('Analyse\\ConfigSection'); $configOutput .= $this->storage->render->renderExpandableChild($model); } // Render the dev-handle field. $editableModel = new Model($this->storage); $data = 'Local open function'; $editableModel->setData($data)->setName($this->storage->config->getDevHandler())->setNormal('\\krexx::')->setType('Input')->setHelpid('localFunction'); $configOutput .= $this->storage->render->renderSingleEditableChild($editableModel); // Render the reset-button which will delete the debug-cookie. $buttonModel = new Model($this->storage); $buttonModel->setName('resetbutton')->setNormal('Reset local settings')->setHelpid('resetbutton'); $configOutput .= $this->storage->render->renderButton($buttonModel); return $configOutput; }
/** * Renders the expendable around the array analysis. * * @return string * The generated markup. */ public function callMe() { $output = ''; $recursionMarker = $this->storage->recursionHandler->getMarker(); $output .= $this->storage->render->renderSingeChildHr(); // Iterate through. foreach ($this->parameters['data'] as $key => &$value) { // We will not output our recursion marker. // Meh, the only reason for the recursion marker // in arrays is because of the $GLOBAL array, which // we will only render once. if ($key === $recursionMarker) { continue; } if (is_string($key)) { $key = $this->storage->encodeString($key); } $model = new Model($this->storage); // Are we dealing with multiline code generation? if ($this->parameters['multiline'] === true) { // Here we tel the Codegen service that we need some // special handling. $model->setMultiLineCodeGen('iterator_to_array'); } if (is_string($key)) { $model->setData($value)->setName($key)->setConnector1('[\'')->setConnector2('\']'); } else { $model->setData($value)->setName($key)->setConnector1('[')->setConnector2(']'); } $output .= $this->storage->routing->analysisHub($model); } $output .= $this->storage->render->renderSingeChildHr(); return $output; }
/** * Iterate though the result of the polled debug methods. * * @return string * The generated markup. */ public function callMe() { $model = new Model($this->storage); $model->setData($this->parameters['data'])->setName('result'); // This could be anything, we need to route it. return $this->storage->routing->analysisHub($model); }
/** * Simply iterate though object constants. * * @return string * The generated markup. */ public function callMe() { $output = ''; // We do not need to check the recursionHandler, this is class // internal stuff. Is it even possible to create a recursion here? // Iterate through. foreach ($this->parameters['data'] as $k => &$v) { $model = new Model($this->storage); $model->setData($v)->setName($k)->setConnector1($this->parameters['classname'] . '::'); $output .= $this->storage->routing->analysisHub($model); } return $output; }
/** * Renders the info of a single method. * * @return string * The generated markup. */ public function callMe() { $data = $this->parameters['data']; $output = ''; foreach ($data as $key => $string) { $model = new Model($this->storage); $model->setData($string)->setName($key)->setType('reflection')->setConnector2('='); if ($key !== 'comments' && $key !== 'declared in' && $key !== 'source') { $model->setNormal($string); } else { $model->setNormal('. . .'); $model->hasExtras(); } $output .= $this->storage->render->renderSingleChild($model); } return $output; }
/** * {@inheritDoc} */ public function renderExpandableChild(Model $model, $isExpanded = false) { // Check for emergency break. if (!$this->storage->emergencyHandler->checkEmergencyBreak()) { return ''; } // We need to render this one normally. $template = $this->getTemplateFileContent('expandableChildNormal'); // Replace our stuff in the partial. $template = str_replace('{name}', $model->getName(), $template); $template = str_replace('{type}', $model->getType(), $template); // Explode the type to get the class names right. $types = explode(' ', $model->getType()); $cssType = ''; foreach ($types as $singleType) { $cssType .= ' k' . $singleType; } $template = str_replace('{ktype}', $cssType, $template); $template = str_replace('{additional}', $model->getAdditional(), $template); $template = str_replace('{connector2}', $this->renderConnector($model->getConnector2()), $template); // Generating our code and adding the Codegen button, if there is // something to generate. $gencode = $this->storage->codegenHandler->generateSource($model); $template = str_replace('{gensource}', $gencode, $template); if ($gencode == ';stop;' || empty($gencode)) { // Remove the button marker, because here is nothing to add. $template = str_replace('{sourcebutton}', '', $template); } else { // Add the button. $template = str_replace('{sourcebutton}', $this->getTemplateFileContent('sourcebutton'), $template); } // Is it expanded? // This is done in the js. $template = str_replace('{isExpanded}', '', $template); $json = $model->getJson(); $json['Help'] = $this->storage->messages->getHelp($model->getHelpid()); $json = json_encode($json); $template = str_replace('{addjson}', $json, $template); return str_replace('{nest}', $this->storage->chunks->chunkMe($this->renderNest($model, false)), $template); }
/** * Dump the possible result of all getter methods * * @param \ReflectionClass $ref * * @param object $data * The object we are currently analysing. * * @return string * The generated markup. */ protected function getAllGetterData(\ReflectionClass $ref, $data) { // Get all public mehtods. $methodList = get_class_methods($data); if (!empty($methodList)) { // Filter them. foreach ($methodList as $key => $method) { if (strpos($method, 'get') !== 0) { unset($methodList[$key]); } else { // We only dump those that have no parameters. $reflectionMethod = $ref->getMethod($method); if (!empty($reflectionMethod->getParameters())) { unset($methodList[$key]); } } } if (!empty($methodList)) { // Got some getters right here. $model = new Model($this->storage); // We need to set al least one connector here to activate // code generation, even if it is a space. $model->setName('Getter')->setType('class internals')->setHelpid('getterHelpInfo')->addParameter('ref', $ref)->addParameter('methodList', $methodList)->addParameter('data', $data)->initCallback('Iterate\\ThroughGetter'); return $this->storage->render->renderExpandableChild($model); } } // There are no getter methods in here. return ''; }
/** * Renders the properties of a class. * * @return string * The generated markup. */ public function callMe() { // I need to preprocess them, since I do not want to render a // reflection property. /* @var \ReflectionClass $ref */ $ref = $this->parameters['ref']; $output = ''; $default = $ref->getDefaultProperties(); foreach ($this->parameters['data'] as $refProperty) { /* @var \ReflectionProperty $refProperty */ $refProperty->setAccessible(true); // Getting our values from the reflection. $value = $refProperty->getValue($this->parameters['orgObject']); $propName = $refProperty->name; if (is_null($value) && $refProperty->isDefault()) { // We might want to look at the default value. $value = $default[$propName]; } // Check memory and runtime. if (!$this->storage->emergencyHandler->checkEmergencyBreak()) { return ''; } // Recursion tests are done in the analyseObject and // iterateThrough (for arrays). // We will not check them here. // Now that we have the key and the value, we can analyse it. // Stitch together our additional info about the data: // public, protected, private, static. $additional = ''; $connector1 = '->'; if ($refProperty->isPublic()) { $additional .= 'public '; } if ($refProperty->isPrivate()) { $additional .= 'private '; } if ($refProperty->isProtected()) { $additional .= 'protected '; } if (is_a($refProperty, '\\Brainworxx\\Krexx\\Analysis\\Flection')) { /* @var \Brainworxx\Krexx\Analyse\Flection $refProperty */ $additional .= $refProperty->getWhatAmI() . ' '; } if ($refProperty->isStatic()) { $additional .= 'static '; $connector1 = '::'; // There is always a $ in front of a static property. $propName = '$' . $propName; } // Stitch together our model $model = new Model($this->storage); $model->setData($value)->setName($propName)->setAdditional($additional)->setConnector1($connector1); $output .= $this->storage->routing->analysisHub($model); } return $output; }
/** * Analysis a backtrace. * * We need to format this one a little bit different than a * normal array. * * @param array $backtrace * The backtrace. * @param int $offset * For some reason, we have an offset of -1 for fatal error backtrace * line number. * * @return string * The rendered backtrace. */ public function analysisBacktrace(array &$backtrace, $offset = 0) { $output = ''; foreach ($backtrace as $step => $stepData) { $model = new Model($this->storage); $model->setName($step)->setType('Stack Frame')->addParameter('data', $stepData)->addParameter('offset', $offset)->initCallback('Analyse\\BacktraceStep'); $output .= $this->storage->render->renderExpandableChild($model); } return $output; }
/** * Render a dump for method info. * * @param array $data * The method analysis results in an array. * @param string $name * The name of the object. * * @return string * The generated markup. */ protected function dumpMethodInfo(array $data, $name) { $paramList = ''; $connector1 = '->'; foreach ($data as $key => $string) { // Getting the parameter list. if (strpos($key, 'Parameter') === 0) { $paramList .= trim($string) . ', '; } if (strpos($data['declaration keywords'], 'static') !== false) { $connector1 = '::'; } } $paramList = str_replace(array('<required> ', '<optional> '), '', $this->storage->encodeString($paramList)); // Remove the ',' after the last char. $paramList = '<small>' . trim($paramList, ', ') . '</small>'; $model = new Model($this->storage); $model->setName($name)->setType($data['declaration keywords'] . ' method')->setConnector1($connector1)->setConnector2('(' . $paramList . ')')->addParameter('data', $data)->initCallback('Iterate\\ThroughMethodAnalysis'); return $this->storage->render->renderExpandableChild($model); }
/** * Try to get the possible result of all getter methods. * * @return string * The generated markup. */ public function callMe() { $output = ''; /** @var \reflectionClass $ref */ $ref = $this->parameters['ref']; foreach ($this->parameters['methodList'] as $methodName) { $propertyName = substr($methodName, 3); // We may be facing different writing styles. // The property we want from getMyProperty() should be named // myProperty, but we can not rely on this. // We will check: // MyProperty // myProperty // myproperty // my_property if ($ref->hasProperty($propertyName)) { $refProp = $ref->getProperty($propertyName); } $realName = lcfirst($propertyName); if ($ref->hasProperty(lcfirst($realName))) { $refProp = $ref->getProperty($realName); } $realName = strtolower($propertyName); if ($ref->hasProperty(strtolower($realName))) { $refProp = $ref->getProperty($realName); } $realName = $this->convertToSnakeCase($propertyName); if ($ref->hasProperty($this->convertToSnakeCase($realName))) { $refProp = $ref->getProperty($realName); } if (empty($refProp)) { // Found nothing :-( $value = null; } else { // We've got ourself a possible result! $refProp->setAccessible(true); $value = $refProp->getValue($this->parameters['data']); } // We need to decide if we are handling static getters. $model = new Model($this->storage); $model->setData($value)->setName($methodName)->setConnector2('()'); if ($ref->getMethod($methodName)->isStatic()) { $model->setConnector1('::'); } else { $model->setConnector1('->'); } $output .= $this->storage->routing->analysisHub($model); } return $output; }
/** * Renders a simple button. * * @param Model $model * The model, which hosts all the data we need. * * @return string * The generated markup from the template files. */ public function renderButton(Model $model) { $template = $this->getTemplateFileContent('singleButton'); $template = str_replace('{help}', $this->renderHelp($model->getHelpid()), $template); $template = str_replace('{text}', $model->getNormal(), $template); return str_replace('{class}', $model->getName(), $template); }
/** * Simply renders the footer and output current settings. * * @param array $caller * Where was kreXX initially invoked from. * @param bool $isExpanded * Are we rendering an expanded footer? * TRUE when we render the settings menu only. * * @return string * The generated markup. */ protected function outputFooter($caller, $isExpanded = false) { // Now we need to stitch together the content of the ini file // as well as it's path. if (!is_readable($this->storage->config->krexxdir . 'config/Krexx.ini')) { // Project settings are not accessible // tell the user, that we are using fallback settings. $path = 'Krexx.ini not found, using factory settings'; // $config = array(); } else { $path = 'Current configuration'; } $model = new Model($this->storage); $model->setName($path)->setType($this->storage->config->krexxdir . 'config/Krexx.ini')->setHelpid('currentSettings')->initCallback('Iterate\\ThroughConfig'); $configOutput = $this->storage->render->renderExpandableChild($model, $isExpanded); return $this->storage->render->renderFooter($caller, $configOutput, $isExpanded); }
/** * Analyses the type and then decides what to do with it * * @param Model $model * The type we are analysing, for example 'private array'. * * @return string * Possible values: * - concatenation * - method * - property */ protected function analyseType(Model $model) { $type = $model->getType(); $multiline = $model->getMultiLineCodeGen(); $concatenation = 'concatenation'; $method = 'method'; $property = 'property'; $stop = 'stop'; // Debug methods are always public. if ($type === 'debug method' || $this->counter === 0) { return $concatenation; } // Test for constants. if ($type === 'class internals' && $model->getName() === 'Constants') { // We must only take the stuff from the constant itself return $stop; } // Test for multiline code generation. if (!empty($multiline)) { return $multiline; } // Test for protected or private. if (strpos($type, 'protected') === false && strpos($type, 'private') === false) { // Is not protected. return $concatenation; } // Test if we are inside the scope. if (self::isInScope($type)) { // We are inside the scope, this value, function or class is reachable. return $concatenation; } // We are still here? Must be a protected method or property. if (strpos($type, 'method') === false) { // This is not a method. return $property; } else { return $method; } }
/** * Dump information about a variable. * * Here everything starts and ends (well, unless we are only outputting * the settings editor). * * @param mixed $data * The variable we want to analyse. * @param string $headline * The headline of the markup we want to produce. Most likely the name of * the variable. */ public function dumpAction($data, $headline = '') { if ($this->storage->emergencyHandler->checkMaxCall()) { // Called too often, we might get into trouble here! return; } $this->storage->reset(); // Find caller. $caller = $this->storage->callerFinder->findCaller(); if ($headline != '') { $caller['type'] = $headline; } else { $caller['type'] = 'Analysis'; } $this->storage->codegenHandler->setScope($caller['varname']); // Set the headline, if it's not set already. if (empty($headline)) { if (is_object($data)) { $headline = get_class($data); } if (is_array($data)) { $headline = 'array'; } if (is_bool($data)) { $headline = 'boolean'; } if (is_float($data)) { $headline = 'float'; } if (is_int($data)) { $headline = 'integer'; } if (is_null($data)) { $headline = 'null'; } if (is_resource($data)) { $headline = 'resource'; } if (is_string($data)) { $headline = 'string'; } } // We need to get the footer before the generating of the header, // because we need to display messages in the header from the configuration. $footer = $this->outputFooter($caller); $this->storage->codegenHandler->checkAllowCodegen(); // Enable code generation only if we were aqble to determine the varname. if ($caller['varname'] != '. . .') { // We were able to determine the variable name and can generate some // sourcecode. $headline = $caller['varname']; } // Start the magic. $model = new Model($this->storage); $model->setData($data)->setName($caller['varname']); $analysis = $this->storage->routing->analysisHub($model); // Now that our analysis is done, we must check if there was an emergency // break. if (!$this->storage->emergencyHandler->checkEmergencyBreak()) { return; } $this->shutdownHandler->addChunkString($this->outputHeader($headline)); $this->shutdownHandler->addChunkString($analysis); $this->shutdownHandler->addChunkString($footer); // Add the caller as metadata to the chunks class. It will be saved as // additional info, in case we are logging to a file. if ($this->storage->config->getSetting('destination') === 'file') { $this->storage->chunks->addMetadata($caller); } }
/** * Renders a backtrace step. * * @return string * The generated markup. */ public function callMe() { $output = ''; // We are handling the following values here: // file, line, function, object, type, args, sourcecode. $stepData = $this->parameters['data']; // File. if (isset($stepData['file'])) { $fileModel = new Model($this->storage); $fileModel->setData($stepData['file'])->setName('File')->setNormal($stepData['file'])->setType('string ' . strlen($stepData['file'])); $output .= $this->storage->render->renderSingleChild($fileModel); } // Line. if (isset($stepData['line'])) { $lineModel = new Model($this->storage); $lineModel->setData($stepData['line'])->setName('Line no.')->setNormal($stepData['line'])->setType('integer'); $output .= $this->storage->render->renderSingleChild($lineModel); } // Sourcecode, is escaped by now. $sourceModel = new Model($this->storage); if (isset($stepData['line'])) { $lineNo = $stepData['line'] + $this->parameters['offset']; $source = trim($this->storage->readSourcecode($stepData['file'], $lineNo, $lineNo - 5, $lineNo + 5)); if (empty($source)) { $source = $this->storage->messages->getHelp('noSourceAvailable'); } } else { $source = $this->storage->messages->getHelp('noSourceAvailable'); } $sourceModel->setData($source)->setName('Sourcecode')->setNormal('. . .')->hasExtras()->setType('PHP'); $output .= $this->storage->render->renderSingleChild($sourceModel); // Function. if (isset($stepData['function'])) { $functionModel = new Model($this->storage); $functionModel->setData($stepData['function'])->setName('Last called function')->setNormal($stepData['function'])->setType('string ' . strlen($stepData['function'])); $output .= $this->storage->render->renderSingleChild($functionModel); } // Object. if (isset($stepData['object'])) { $objectModel = new Model($this->storage); $objectModel->setData($stepData['object'])->setName('Calling object'); $output .= $this->storage->routing->analyseObject($objectModel); } // Type. if (isset($stepData['type'])) { $typeModel = new Model($this->storage); $typeModel->setData($stepData['type'])->setName('Call type')->setNormal($stepData['type'])->setType('string ' . strlen($stepData['type'])); $output .= $this->storage->render->renderSingleChild($typeModel); } // Args. if (isset($stepData['args'])) { $argsModel = new Model($this->storage); $argsModel->setData($stepData['args'])->setName('Arguments from the call'); $output .= $this->storage->routing->analyseArray($argsModel); } return $output; }