<?php
namespace nikaverro\dev\help;
use Bitrix\Main\Loader;
Loader::includeModule('iblock');
class Help {
const IBLOCK_HELP_ID = 158;
const PATH_TO_FILES = [
"html" => "/upload/learning/html/",
"images" =>"/upload/learning/img/"
];
const PROPS_HELP = [
"keys" => 744, //где ключи лежат
"file" => 756 //где имя файла мелкими буквами
];
const IBLOCK_SECTION_DEFAULT_ID = 1076; //раздел по дефолту, куда грузим
/*порядок действий
//загрузить html images /upload/learning/
use nikaverro\dev\help\Help;
Help::SetRightPages(); //заполняем свойство PAGE в исходном хелпе верный по ключу
Help::SetRightKeys(); //добавляем новые Верные ключи для страниц
Help::UpdatePropPageWithoutKeys(); //апдейтим свойство PAGE для статей БЕЗ ключа, которых нет в ali (по названию статьи)
$res = Help::GetArticlesWithoutPropPages(); //получим статьи БЕЗ заполненного свойства page
$res2 = Help::GetNotFoundPages();//получим файлы, которых нет в хелпе (проперти PAGE такой НЕТ) - или новая или не сопопставили
echo "<pre>";
print_r($res);
print_r($res2);
echo "</pre>";
//заполнить вручную массив в GetManualPages();
Help::UpdateDetailTextByManualsPage();
Help::GetArticlesWithoutPropPages();//проверим статьи БЕЗ заполненного свойства page
Help::UpdateDetailTextByPage(true); //апдейтим текст детальный по свойству PAGE, добавляем новые
Help::GetNotExistingPages()//файлы, которые есть в ali, но нет их html - информационно
*/
public static function UpdateDetailTextByPage($bUpdate = false){
global $USER;
$el = new \CIBlockElement;
$elNew = 1;
$dir = $_SERVER["DOCUMENT_ROOT"] . self::PATH_TO_FILES["html"];
$arPagesAli = self::GetPagesAli(true);
$arParamsCode = array( "replace_space" => "-", "replace_other" => "-" );
if ($handle = opendir($dir)) {
$arPagesIblock = self::GetPagesFromIblock();
while (false !== ($file = readdir($handle))) {
if ($file == '.' || $file == '..') {
continue;
}
$file1 = $dir.$file;
if (is_file($file1)) {
$fileLower = strtolower($file);
if (isset($arPagesIblock[$fileLower])) {
if ($bUpdate) {
$arArticle = self::ParsingArticle($file1, $arPagesIblock[$fileLower]["name"],$arPagesIblock);
if (!empty($arArticle["text"])) {
$arItemUpdated = [
"DETAIL_TEXT" => $arArticle["text"],
];
if(!empty($arArticle["title"])){
$arItemUpdated["NAME"] = $arArticle["title"];
}
$el->Update($arPagesIblock[$fileLower]["id"], $arItemUpdated);
}
}
}
else {
//добавляем НОВЫЕ
if ($bUpdate) {
$arArticle = self::ParsingArticle($file1, "new ".$elNew, $arPagesIblock);
$elNew++;
if (!empty($arArticle["text"])) {
$arKeys = [];
$fileLower = strtolower($file);
foreach ($arPagesAli as $keyAli => $pageAli){
if($fileLower == $pageAli){
$arKeys[] = $keyAli;
}
}
$codeElement = \Cutil::translit( $arArticle["title"], "en", $arParamsCode );
$arItemNew = [
"NAME" => $arArticle["title"],
"DETAIL_TEXT" => $arArticle["text"],
"DETAIL_TEXT_TYPE"=>"html",
"IBLOCK_ID" => self::IBLOCK_HELP_ID,
"PROPERTY_VALUES" => [
self::PROPS_HELP["file"] => $fileLower,
self::PROPS_HELP["keys"]=>$arKeys
],
"IBLOCK_SECTION_ID" => self::IBLOCK_SECTION_DEFAULT_ID,
"ACTIVE" => "Y",
"MODIFIED_BY" => $USER->GetID(),
"CODE" => $codeElement
];
if($PRODUCT_ID = $el->Add($arItemNew)) {
echo "New ID: ".$PRODUCT_ID."<br>";
}
else {
$bAdd = false;
for ($i=0; $i<50; $i++ ) {
$arItemNew["CODE"] = $codeElement . "-" . $i;
if ($PRODUCT_ID = $el->Add($arItemNew)) {
$bAdd = true;
echo "New ID: " . $PRODUCT_ID . "<br>";
break;
}
}
if(!$bAdd) {
echo "Error: " . $el->LAST_ERROR . " " . $codeElement . "<br>";
}
}
}
}
}
}
}
}
}
public static function SetRightPages(){ //заполняем свойство PAGE в исходном хелпе верный по ключу
$arPages = self::GetPagesAli();
$el = new \CIBlockElement;
$found = [1];
foreach ($arPages as $key => $page) {
$fileNameTemp = $_SERVER["DOCUMENT_ROOT"] . self::PATH_TO_FILES["html"] . $page;
$fileName = self::FileExistsCaseInsensitive($fileNameTemp, false);
if ($fileName){
$arFilter = array(
"IBLOCK_ID" => self::IBLOCK_HELP_ID,
"ACTIVE" => "Y",
"PROPERTY_".self::PROPS_HELP["keys"] => $key,
"!ID" => $found
);
$arSelect = array("ID");
$res = \CIBlockElement::GetList(array("sort" => "asc"), $arFilter, false, array("nPageSize" => 50, "iNumPage" => 1), $arSelect);
if ($arItem = $res->Fetch()) {
$found[] = $arItem["ID"];
\CIBlockElement::SetPropertyValuesEx($arItem["ID"], self::IBLOCK_HELP_ID, [self::PROPS_HELP["file"] => strtolower($page)]);
}
}
}
}
public static function SetRightKeys(){ //добавляем ключи для страниц
$arPages = self::GetPagesAli();
foreach ($arPages as $key => $page) {
$fileNameTemp = $_SERVER["DOCUMENT_ROOT"] . self::PATH_TO_FILES["html"] . $page;
$fileName = self::FileExistsCaseInsensitive($fileNameTemp, false);
if ($fileName) {
$arFilter = array(
"IBLOCK_ID" => self::IBLOCK_HELP_ID,
"ACTIVE" => "Y",
"PROPERTY_".self::PROPS_HELP["keys"] => $key,
//"!ID" => $found
);
$arSelect = array("ID");
$res = \CIBlockElement::GetList(array("sort" => "asc"), $arFilter, false, array("nPageSize" => 50, "iNumPage" => 1), $arSelect);
if ($arItem = $res->Fetch()) {
}
else{
$arFilter = Array(
"IBLOCK_ID"=>self::IBLOCK_HELP_ID,
"ACTIVE"=>"Y",
"PROPERTY_".self::PROPS_HELP["file"] => strtolower($page),
);
$arSelect = Array("ID", "NAME","IBLOCK_ID");
$res = \CIBlockElement::GetList(Array("sort"=>"asc"), $arFilter, false, Array("nPageSize"=>50,"iNumPage"=>1), $arSelect);
if($arItem = $res->Fetch()){ //значит нет ключа
$res = \CIBlockElement::GetProperty(self::IBLOCK_HELP_ID, $arItem["ID"], "sort", "asc", array("ID" => self::PROPS_HELP["keys"]));
$arValues = [];
while ($arValue = $res->GetNext()){
$arValues = [$arValue["VALUE"]];
}
$arValues[] = $key;
\CIBlockElement::SetPropertyValuesEx($arItem["ID"], self::IBLOCK_HELP_ID,[self::PROPS_HELP["keys"]=>$arValues]);
}
}
}
}
}
public static function UpdateDetailTextByManualsPage(){
$arPages = self::GetManualPages();
foreach ($arPages as $id => $page){
\CIBlockElement::SetPropertyValuesEx($id, self::IBLOCK_HELP_ID, [self::PROPS_HELP["file"] => strtolower($page)]);
}
}
public static function ParsingArticleTitle($fileName){//парсим html, ищем title
$doc = new \DOMDocument;
$result = "";
if(file_exists($fileName)) {
$doc->loadhtmlfile($fileName);
$ps = $doc->getElementsByTagName('p');
foreach ($ps as $p){
$classes = explode(" ",$p->getAttribute('class'));
if(in_array("WD_phTopicTitle",$classes)){//ищем тут по умолчанию
$result = $p->nodeValue;
break;
}
elseif(in_array("WD_Heading1",$classes)){//если не найдется WD_phTopicTitle
$as = $p->getElementsByTagName('a');
$bfind = false;
foreach ($as as $a){
if(!empty($a->nodeValue)){
$result = $a->nodeValue;
$bfind = true;
break;
}
}
if(!$bfind) {
$result = $p->nodeValue;
}
}
}
}
return $result;
}
public static function ParsingArticle($fileName, $elementName,$arPagesIblock){//парсим html
$doc = new \DOMDocument;
$result = ["title"=>$elementName,"text"=>""];
$imagePrefix = ["CAD drafting", "CAD software", "CAD drawing"];
if(file_exists($fileName)) {
$doc->loadhtmlfile($fileName);
$body = $doc->getElementsByTagName('body');
if ($body && 0 < $body->length) {
$body = $body->item(0);
$ps = $body->getElementsByTagName('p');
foreach ($ps as $p) {
if ($p->hasAttribute('class')) {
$classes = explode(" ", $p->getAttribute('class'));
if(in_array("WD_phTopicTitle",$classes)) {
if(!empty($p->nodeValue)){
$result["title"] = $p->nodeValue;
break;
}
}
elseif(in_array("WD_Heading1",$classes)) {//если не найдется WD_phTopicTitle
$as = $p->getElementsByTagName('a');
foreach ($as as $a){
if(!empty($a->nodeValue)){
$result["title"] = $a->nodeValue;
break 2;
}
}
if(!empty($p->nodeValue)){
$result["title"] = $p->nodeValue;
break;
}
}
}
}
$ps2 = [];
foreach ($ps as $p){
$ps2[] = $p;
}
$ps = array_reverse($ps2);
//заголовок ищем
foreach ($ps as $p){
if($p->hasAttribute('class')){
$classes = explode(" ",$p->getAttribute('class'));
if(
in_array("WD_phTopicTitle",$classes) ||
in_array("WD_phTopicID",$classes) ||
in_array("WD_Heading1",$classes) //||
//in_array("WD_Heading2",$classes)
){
try {
$body->removeChild($p);
} catch (Exception $e) {
$p->parentNode->removeChild($p);
}
}
elseif(in_array("WD_Heading2",$classes)){
$as = $p->getElementsByTagName('a');
$titleTemp = "";
foreach ($as as $a){
if(!empty($a->nodeValue)){
$titleTemp = strtolower(trim($a->nodeValue));
break;
}
}
if(empty($titleTemp)){
foreach ($as as $a){
try {
$p->removeChild($a);
} catch (\Exception $e) {
$a->parentNode->removeChild($a);
}
}
$titleTemp = strtolower(trim($p->nodeValue));
}
if($titleTemp == strtolower(trim($result["title"]))){
try {
$body->removeChild($p);
} catch (\Exception $e) {
$p->parentNode->removeChild($p);
}
}
else {
$p->setAttribute("class", "h3 mt-3");
}
}
elseif(in_array("WD_Heading3",$classes)){
$as = $p->getElementsByTagName('a');
$titleTemp = "";
foreach ($as as $a){
if(!empty($a->nodeValue)){
$titleTemp = strtolower(trim($a->nodeValue));
break;
}
}
if(empty($titleTemp)){
foreach ($as as $a){
try {
$p->removeChild($a);
} catch (\Exception $e) {
$a->parentNode->removeChild($a);
}
}
$titleTemp = strtolower(trim($p->nodeValue));
}
if($titleTemp == strtolower(trim($result["title"]))){
try {
$body->removeChild($p);
} catch (\Exception $e) {
$p->parentNode->removeChild($p);
}
}
else {
$p->setAttribute("class", "h4 mt-3");
}
}
elseif(in_array("WD_Heading4",$classes) || in_array("WD_Heading5",$classes)){
$as = $p->getElementsByTagName('a');
$titleTemp = "";
foreach ($as as $a){
if(!empty($a->nodeValue)){
$titleTemp = strtolower(trim($a->nodeValue));
break;
}
}
if(empty($titleTemp)){
foreach ($as as $a){
try {
$p->removeChild($a);
} catch (\Exception $e) {
$a->parentNode->removeChild($a);
}
}
$titleTemp = strtolower(trim($p->nodeValue));
}
if($titleTemp == strtolower(trim($result["title"]))){
try {
$body->removeChild($p);
} catch (\Exception $e) {
$p->parentNode->removeChild($p);
}
}
else {
$p->setAttribute("class", "h5 mt-2");
}
}
elseif (in_array("WD_phnormal",$classes) || in_array("WD_Normal",$classes)){
$p->removeAttribute("class");
}
}
}
$images = $body->getElementsByTagName('img');
$i = 0;
foreach ($images as $image) {
if($image->hasAttribute('src')) {
$src = $image->getAttribute('src');
$src = self::PATH_TO_FILES["images"].$src;
$image->setAttribute('src', $src);
$alt = $imagePrefix[$i%3]." ".$result["title"]." ".$i;
$image->setAttribute('alt', $alt);
$image->removeAttribute("style");
$i++;
}
}
$divs = $body->getElementsByTagName('div');
foreach ($divs as $div){
$div->removeAttribute("style");
}
$as = $body->getElementsByTagName('a');
foreach ($as as $a){
$href = $a->getAttribute('href');
if(!empty($href)){
if(strpos($href,"#") !== false) {
$href = strtolower(substr($href, 0, strpos($href, "#")));
}
else{
$href = strtolower($href);
}
if(isset($arPagesIblock[$href])){
$a->setAttribute('href', "/learning/online-help/".$arPagesIblock[$href]["code"]."/");
}
else{
/*if(!in_array($href,["https://online-help.nanocad.com/nc23_help", "mailto:support@nanocad.com"])){ //эти не меняем
if($href == "http://www.nanocad.com"){
$a->setAttribute('href', "https://www.nanocad.com");
}
else {
if(!empty($href)){
echo $href . "<br>";
}
else {
$a->setAttribute('href', "#");
}
}
}*/
}
}
}
$scripts = $body->getElementsByTagName('script');
$scripts2 = [];
foreach ($scripts as $script){
$scripts2[] = $script;
}
$scripts = array_reverse($scripts2);
foreach ($scripts as $script) {
$script->setAttribute('src',"");
try {
$body->removeChild($script);
} catch (\Exception $e) {
$script->parentNode->removeChild($script);
}
}
$result["text"] = self::DOMinnerHTML($body);
}
}
return $result;
}
public static function GetNotExistingPages(){//файлы, которые есть в ali, но нет их html
$arPages = self::GetPagesAli();
$files = [];
foreach ($arPages as $key => $page) {
$fileName = $_SERVER["DOCUMENT_ROOT"] . self::PATH_TO_FILES["html"] . $page;
if (!self::FileExistsCaseInsensitive($fileName, false)) {
$files[$key] = $page;
}
}
return $files;
}
public static function GetPagesFromIblock(){
$result = [];
$arFilter = [
"IBLOCK_ID" => self::IBLOCK_HELP_ID,
"ACTIVE" => "Y",
"!PROPERTY_".self::PROPS_HELP["file"] => false
];
$arSelect = array("ID","NAME","IBLOCK_ID","CODE","PROPERTY_".self::PROPS_HELP["file"]);
$res = \CIBlockElement::GetList(array("sort" => "asc"), $arFilter, false, array("nPageSize" => 1000, "iNumPage" => 1), $arSelect);
while($arItem = $res->Fetch()) {
$result[$arItem["PROPERTY_".self::PROPS_HELP["file"]."_VALUE"]] = [
"id" => $arItem["ID"],
"code" => $arItem["CODE"],
"name" => $arItem["NAME"]
];
}
return $result;
}
public static function GetNotFoundPages(){
$result = [];
$dir = $_SERVER["DOCUMENT_ROOT"] . self::PATH_TO_FILES["html"];
//$arPages = GetPagesAli(true);
if ($handle = opendir($dir)) {
$arPages = [];
$arFilter = [
"IBLOCK_ID" => self::IBLOCK_HELP_ID,
"ACTIVE" => "Y",
"!PROPERTY_".self::PROPS_HELP["file"] => false
];
$arSelect = array("ID","NAME","IBLOCK_ID","PROPERTY_".self::PROPS_HELP["file"]);
$res = \CIBlockElement::GetList(array("sort" => "asc"), $arFilter, false, array("nPageSize" => 1000, "iNumPage" => 1), $arSelect);
while($arItem = $res->Fetch()) {
$arPages[$arItem["PROPERTY_".self::PROPS_HELP["file"]."_VALUE"]] = $arItem;
}
while (false !== ($file = readdir($handle))) {
if ($file == '.' || $file == '..') {
continue;
}
$file1 = $dir . $file;
if (is_file($file1)) {
if(!isset($arPages[strtolower($file)])){
$name = self::ParsingArticleTitle($file1);
$result[] = $file." ".$name;
}
}
}
}
return $result;
}
public static function UpdatePropPageWithoutKeys(){//апдейтим свойство PAGE для статей БЕЗ ключа, которых нет в ali
$result = [];
$dir = $_SERVER["DOCUMENT_ROOT"] . self::PATH_TO_FILES["html"];
if ($handle = opendir($dir)) {
$arPages = self::GetPagesAli();
while (false !== ($file = readdir($handle))) {
if ($file == '.' || $file == '..') {
continue;
}
$file1 = $dir.$file;
if (is_file($file1)) {
if(!in_array($file,$arPages)){//нет тега для файла
//попробуем искать по имени
$name = self::ParsingArticleTitle($file1); //берем имя статьи из файла
if(!empty($name)){
$arFilter = array(
"IBLOCK_ID" => self::IBLOCK_HELP_ID,
"ACTIVE" => "Y",
"NAME" => "%".$name."%",
[
"LOGIC"=>"OR",
["PROPERTY_".self::PROPS_HELP["file"] => false],
["PROPERTY_".self::PROPS_HELP["file"] => $file],
["PROPERTY_".self::PROPS_HELP["file"] => strtolower($file)],
]
);
$arSelect = array("ID","NAME");
$res = \CIBlockElement::GetList(array("sort" => "asc"), $arFilter, false, array("nPageSize" => 50, "iNumPage" => 1), $arSelect);
if ($arItem = $res->Fetch()) {
//echo $file." ".$name." ".$arItem["NAME"]." ".$arItem["ID"]."<br>";
\CIBlockElement::SetPropertyValuesEx($arItem["ID"], self::IBLOCK_HELP_ID,[self::PROPS_HELP["file"]=>strtolower($file)]);
}
else{
//echo $file." ".$name." <br>";
$result[]=$file;
}
}
}
}
}
closedir($handle);
}
return $result;
}
public static function GetArticlesWithoutPropPages(){
$result = [];
$arFilter = array(
"IBLOCK_ID" => self::IBLOCK_HELP_ID,
"ACTIVE" => "Y",
"PROPERTY_".self::PROPS_HELP["file"] => false
);
$arSelect = array("ID","NAME");
$res = \CIBlockElement::GetList(array("sort" => "asc"), $arFilter, false, array("nPageSize" => 5000, "iNumPage" => 1), $arSelect);
while($arItem = $res->Fetch()) {
//if(empty(GetManualPageById($arItem["ID"]))) {
$result[$arItem["ID"]] = $arItem["NAME"];
//}
}
return $result;
}
public static function FileExistsCaseInsensitive($fileName, $caseSensitive = true) {
if(file_exists($fileName)) {
return $fileName;
}
if($caseSensitive) return false;
// Handle case insensitive requests
$directoryName = dirname($fileName);
$fileArray = glob($directoryName . '/*', GLOB_NOSORT);
$fileNameLowerCase = strtolower($fileName);
foreach($fileArray as $file) {
if(strtolower($file) == $fileNameLowerCase) {
return $file;
}
}
return false;
}
public static function DOMinnerHTML(DOMNode $element){
$innerHTML = "";
$children = $element->childNodes;
foreach ($children as $child){
$innerHTML .= $element->ownerDocument->saveHTML($child);
}
return $innerHTML;
}
public static function GetPagesAli($bLower = false){
$arPages = [
"IDH_Default"=>"IDT_WorkInApp.htm",
"Welcome"=>"IDT_WorkInApp.htm",
//тут дофига еще страниц
];
if($bLower){
$arPagesLower = [];
foreach ($arPages as $key => $page){
$arPagesLower[$key] = strtolower($page);
}
$arPages = $arPagesLower;
}
return $arPages;
}
public static function GetManualPages(){ //ручное сопоставление
$arPages = [
16036383 => false,//3D-Component Features
16036424 => "IDT_Materials.htm",//Materials
16045403 => false,//Save changes?
16045404 => false,//Saving in demo mode
16045405 => false,//Switch it to 3D render mode
16036199 => "IDH_NPC_Sect_Unrestricted.htm",//Point Clouds Unrestricted Section
16036439 => "IDT_RunFromCmdLine.htm",//Run from Command Lline
16036168 => "IDH_NG_Mesh_Vertex_Move.htm",//Moving a vertex
16036263 => "IDT_UndoRedo.htm",//Redo Commands
16036076 => "IDT_Interface_Menu.htm",//Main Menu
16036394 => "IDT_2DConstraints.htm",//Constraints
16036420 => "IDT_IsolateObj.htm",//Control the Display of Objects (Isolation)
16036441 => false,//Selection of superimposed objects
16036433 => false,//Selection of objects
16036124 => "IDH_MergeAndDuplicate.htm",//Rasterization
16035997 => "IDH_DimStylesCmd_Modify.htm",//Dimension styles
16036258 => false,//Insert material
];
return $arPages;
}
}
|