/** * Warning! This function may call overloaded functions by contentfields with tests consomming high cpu time * (such as connecting to a database for checking that valid user/pwd have been edited). * This function should be only called when it's really needed, and should never be called more than one time. * This function performs ALL possible tests for checking contentfields values validity. * * @param $oContentParent content for which fieldValues/subcontents will be set if the test is success */ final function testContentFieldValues($amFieldValuesOrSubContents, $oContentParent) { AnwUtils::checkFriendAccess(array("AnwStructuredContent", "AnwStructuredContentField")); //test multiplicity $this->testContentFieldMultiplicity($amFieldValuesOrSubContents); if ($this instanceof AnwStructuredContentField_atomic) { //test each value foreach ($amFieldValuesOrSubContents as $sFieldValue) { if (is_array($sFieldValue) || is_object($sFieldValue)) { throw new AnwUnexpectedException("testContentFieldValues on atomic: not a string"); } //here we don't return a simple 'AnwInvalidContentFieldValueException' to prevent unauthorized users to access PHP source //this will display a big ACL error page instead of edit form... if (AnwUtils::contentHasPhpCode($sFieldValue)) { AnwCurrentSession::getUser()->checkPhpEditionAllowed(); } //check JS permission if (AnwUtils::contentHasJsCode($sFieldValue) && !AnwCurrentSession::getUser()->isJsEditionAllowed()) { $sError = AnwComponent::g_editcontent("err_contentfield_acl_js"); throw new AnwInvalidContentFieldValueException($sError); } //specific tests for atomic fields $this->testContentFieldValueAtomic($sFieldValue); } //if no error, test all atomic values together $this->testAllContentFieldValuesAtomic($amFieldValuesOrSubContents); } else { //test each subcontents occurence foreach ($amFieldValuesOrSubContents as $oContent) { if (!$oContent instanceof AnwStructuredContent) { throw new AnwUnexpectedException("testContentFieldValues on composed: not a subcontent"); } //test subsubcontents $aoSubContentFields = $this->getContentFields(); foreach ($aoSubContentFields as $oSubContentField) { //recursive test $amSubValuesOrSubContents = null; $sSubContentFieldName = $oSubContentField->getName(); if ($oSubContentField instanceof AnwStructuredContentField_atomic) { $amSubValuesOrSubContents = $oContent->getContentFieldValues($sSubContentFieldName); } else { $amSubValuesOrSubContents = $oContent->getSubContents($sSubContentFieldName); } $oSubContentField->testContentFieldValues($amSubValuesOrSubContents, $oContent); } //specific tests for composed fields - at last $this->testContentFieldValueComposed($oContent); } //if no error, test all subcontents together $this->testAllContentFieldValuesComposed($amFieldValuesOrSubContents); } }
function renderEditHtmlForm($bFromPost, $sFormUrl = "", $sSuffix = "", $oContentOriginal = null) { $sHtmlEditForm = ""; //special process for the first call if ($oContentOriginal == null) { $oContentOriginal = $this; $oContentOriginal->bHtmlEditFormHasErroneousFields = false; $oContentOriginal->bHtmlEditFormHasPhpCode = false; $oContentOriginal->bHtmlEditFormHasJsCode = false; $oContentOriginal->nHtmlEditFormCountErroneousChild = 0; $sFormUrl = str_replace('&', '&', $sFormUrl); AnwAction::headJs('var g_editcontentform_url="' . AnwUtils::escapeQuote($sFormUrl) . '";'); AnwAction::headEditContent(); //render tabs if any $aoFieldsTabs = $this->getContentFieldsTabs(); if (count($aoFieldsTabs) > 0) { $sHtmlTabs = ""; foreach ($aoFieldsTabs as $oFieldTab) { $sHtmlTabs .= $oFieldTab->renderEditTab($sSuffix); } $sHtmlEditForm .= <<<EOF <div class="contentfield_tabs"> \t{$sHtmlTabs} \t<div class="break;"></div> </div> EOF; } } $aoContentFields = $this->getContentFieldsContainer()->getContentFields(); foreach ($aoContentFields as $oContentField) { $nPreviousCountErroneousChild = $oContentOriginal->nHtmlEditFormCountErroneousChild; $sFieldName = $oContentField->getName(); $asValuesForRender = array(); $asFieldValues = array(); $aoSubContents = array(); $bHasOverridingValues = null; //do not load from post when contentfield is hidden if ($bFromPost && !$oContentField->isDisplayed()) { $bReallyFromPost = false; } else { $bReallyFromPost = $bFromPost; } /***************************************************************************** * CONTENTFIELD CONTAINER : recursively get value from it's subcontentfields *****************************************************************************/ if ($oContentField instanceof AnwStructuredContentField_composed) { if (!$bReallyFromPost) { // shared code for multiplicity single or multiple try { $aoSubContents = $this->getSubContents($sFieldName); } catch (AnwUnexpectedException $e) { //contentfield_container don't exist already. create it. $aoSubContents = array($this->newContent($oContentField)); } } else { $aoSubContents = array(); if ($oContentField->isMultiple()) { //create as many empty subcontents as instances edited from post $asFieldsIdsFromPost = AnwEnv::_POST($oContentField->getInputName($sSuffix), array()); foreach ($asFieldsIdsFromPost as $sFieldIdFromPost) { $aoSubContents[$sFieldIdFromPost] = $this->newContent($oContentField); } } else { //only 1 empty instance $aoSubContents[] = $this->newContent($oContentField); } } foreach ($aoSubContents as $sIndice => $oSubContent) { //update suffix if (!$bReallyFromPost) { $sSuffixId = AnwUtils::genUniqueIdNumeric(); } else { $sSuffixId = $sIndice; } $sNewSuffix = $oContentField->updateSuffix($sSuffix, $sSuffixId); $sSubRender = $oSubContent->renderEditHtmlForm($bReallyFromPost, $sFormUrl, $sNewSuffix, $oContentOriginal); //recursive call //$asValuesForRender[$sSuffixId] = $sSubRender; $asValuesForRender[$sSuffixId] = array(self::IDX_SUBCONTENT => $oSubContent, self::IDX_RENDERED => $sSubRender); if ($oContentField->isCollapsed() || $oContentField->isCollapsedChild()) { $bWasCollapsingEnabled = AnwStructuredContentField::getDoCollapsing(); AnwStructuredContentField::setDoCollapsing(false); $sSubRenderUncollapsed = $oSubContent->renderEditHtmlForm($bReallyFromPost, $sFormUrl, $sNewSuffix, $oContentOriginal); //recursive call $asValuesForRender[$sSuffixId]['UNCOLLAPSED'] = $sSubRenderUncollapsed; AnwStructuredContentField::setDoCollapsing($bWasCollapsingEnabled); } //only after calling render on subContent! //$asFieldValues[] = $oSubContent->toXmlString(); } $bHasOverridingValues = self::hasOverridingValues($oContentField, $aoSubContents); if ($oContentField->isMultiple()) { if (!$oContentField->hasDefaultSubContents()) { $bHasOverridingValues = false; //special case } } else { if (!$oContentField->hasSetDefaultValues()) { $bHasOverridingValues = false; //special case } } } else { if (!$bReallyFromPost) { $asFieldValues = $this->getContentFieldValues($sFieldName); } else { $asFieldValues = $oContentField->getValuesFromPost($sSuffix); } $asValuesForRender = $asFieldValues; $bHasOverridingValues = self::hasOverridingValues($oContentField, $asFieldValues); if (!$oContentField->hasSetDefaultValues()) { $bHasOverridingValues = false; //special case } } $sFieldError = false; // - run the test for any _atomic field. // - only run the test for _composed fields which dont't have erroneous childs (important for security reasons, to not trigger test() procedure of these composed fields on unsafe values) if ($oContentOriginal->nHtmlEditFormCountErroneousChild == $nPreviousCountErroneousChild) { //test values and multiplicity (even for composed fields) try { if ($oContentField instanceof AnwStructuredContentField_atomic) { $oContentField->testContentFieldValues($asFieldValues, $this); } else { $oContentField->testContentFieldValues($aoSubContents, $this); } } catch (AnwException $e) { //here we can get errors from php edition //display error $sInputName = $oContentField->getInputName($sSuffix); $sFieldError = str_replace('#CONTENTFIELDINPUTID#', $sInputName, $e->getMessage()); $oContentOriginal->bHtmlEditFormHasErroneousFields = true; $oContentOriginal->nHtmlEditFormCountErroneousChild++; //quick hack to solve the following problem: //if user enters invalid XML code, in a contentfield such as _xml //the system would fail on setContentFieldValues() or later, //when trying to load invalid XML from the content. // //so we replace erroneous values by a valid-xml string. //these erroneous values should never be read later : // - test for this contentfield was done before // - render is done on $asValuesForRender, so that user views erroneous in edit inputs // - if this contentfield is child of a container, the container won't do the test as it contains already erroneous values if ($e instanceof AnwInvalidContentFieldValueException && $oContentField instanceof AnwStructuredContentField_atomic) { $sErroneousValue = '#ERRONEOUSVALUE#'; foreach ($asFieldValues as $nValueIndice => $null) { $asFieldValues[$nValueIndice] = $sErroneousValue; } } } /* catch(AnwException $e){ //should never go here print 'ERROR 62'; print_r($e); exit; }*/ } /*else { $sFieldError = "(test skipped)"; }*/ //render it now if ($oContentField->isDisplayed()) { $sHtmlEditForm .= $oContentField->renderEditInputs($asValuesForRender, $sSuffix, $bHasOverridingValues, $sFieldError); } if ($bReallyFromPost) { //update content for preview/save if ($oContentField instanceof AnwStructuredContentField_atomic) { $this->setContentFieldValues($sFieldName, $asFieldValues); } else { $this->setSubContents($sFieldName, $aoSubContents); } } if ($oContentField instanceof AnwStructuredContentField_atomic) { //check acls - are these checks still needed, as test was integrated in class_contentfield? foreach ($asFieldValues as $mContentFieldValue) { //check PHP permission $bHasPhpCode = AnwUtils::contentHasPhpCode($mContentFieldValue); if ($bHasPhpCode) { $oContentOriginal->bHtmlEditFormHasPhpCode = true; AnwCurrentSession::getUser()->checkPhpEditionAllowed(); } //check JS permission $bHasJsCode = AnwUtils::contentHasJsCode($mContentFieldValue); if ($bHasJsCode) { $oContentOriginal->bHtmlEditFormHasJsCode = true; AnwCurrentSession::getUser()->checkJsEditionAllowed(); } } } } return $sHtmlEditForm; }
private function checkPermissions($sPageName, $sPageLang, $sPageContent) { $asNotices = array(); //check that page don't exist if (!AnwPage::isAvailablePageName($sPageName)) { $asNotices[] = $this->t_("notice_exists"); } //check PHP permission if (AnwUtils::contentHasPhpCode($sPageContent) && !AnwCurrentSession::getUser()->isPhpEditionAllowed()) { $asNotices[] = $this->t_("notice_php"); } //check JS permission if (AnwUtils::contentHasJsCode($sPageContent) && !AnwCurrentSession::getUser()->isJsEditionAllowed()) { $asNotices[] = $this->t_("notice_js"); } //check ACL permission : create and edit if (!AnwCurrentSession::isActionAllowed($sPageName, "create", $sPageLang) || !AnwCurrentSession::isActionAllowed($sPageName, "edit", $sPageLang)) { $asNotices[] = $this->t_("notice_acl"); } return $asNotices; }
protected function _setContent($oContent, $oSimilarContentForCheck, $bSecurityChecks = true) { if (ANWIKI_DEVEL) { self::debug("_setContent: " . htmlentities($oContent->toXmlString())); } if (!(is_int($oSimilarContentForCheck) && $oSimilarContentForCheck == -1)) { if (ANWIKI_DEVEL) { self::debug("_setContent: similar was: " . htmlentities($oSimilarContentForCheck->toXmlString())); } self::checkSimilarContents(array($oContent, $oSimilarContentForCheck)); } if ($bSecurityChecks) { //check user permissions once again $sContentAsString = $oContent->toXmlString(); //check PHP code edition if (AnwUtils::contentHasPhpCode($sContentAsString)) { AnwCurrentSession::getUser()->checkPhpEditionAllowed(); } //check unsafe code edition if (AnwUtils::contentHasJsCode($sContentAsString)) { AnwCurrentSession::getUser()->checkJsEditionAllowed(); } } $this->oPreviousContent = $this->oContent; //may be null $this->oContent = $oContent; $this->touchInfosContent(); }