2016-12-19 16:56:52 +01:00
#!/usr/bin/env php
< ? php
2019-10-28 22:39:23 +01:00
/**
2020-02-17 14:13:46 +01:00
* Copyright 2016 - 2020 Daniil Gentili
2019-10-28 22:39:23 +01:00
* ( https :// daniil . it )
* This file is part of MadelineProto .
* MadelineProto is free software : you can redistribute it and / or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation , either version 3 of the License , or ( at your option ) any later version .
* MadelineProto is distributed in the hope that it will be useful , but WITHOUT ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE .
* See the GNU Affero General Public License for more details .
* You should have received a copy of the GNU General Public License along with MadelineProto .
* If not , see < http :// www . gnu . org / licenses />.
*/
2023-07-14 16:34:52 +02:00
use danog\ClassFinder\ClassFinder ;
2019-12-14 16:47:04 +01:00
use danog\MadelineProto\API ;
2023-07-14 16:34:52 +02:00
use danog\MadelineProto\EventHandler\Message\ServiceMessage ;
use danog\MadelineProto\EventHandler\Update ;
use danog\MadelineProto\Lang ;
2020-06-16 17:52:55 +02:00
use danog\MadelineProto\Logger ;
use danog\MadelineProto\Magic ;
2019-12-14 16:47:04 +01:00
use danog\MadelineProto\MTProto ;
2020-09-24 20:49:34 +02:00
use danog\MadelineProto\Settings\Logger as SettingsLogger ;
2023-07-14 16:34:52 +02:00
use danog\MadelineProto\Settings\TLSchema ;
use danog\MadelineProto\TL\TL ;
2021-12-21 14:44:39 +01:00
use danog\MadelineProto\Tools ;
2023-07-14 16:34:52 +02:00
use danog\PhpDoc\PhpDoc ;
use danog\PhpDoc\PhpDoc\MethodDoc ;
2024-04-06 19:21:12 +02:00
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTextNode ;
use PHPStan\PhpDocParser\Lexer\Lexer ;
use PHPStan\PhpDocParser\Parser\ConstExprParser ;
use PHPStan\PhpDocParser\Parser\PhpDocParser ;
use PHPStan\PhpDocParser\Parser\TokenIterator ;
use PHPStan\PhpDocParser\Parser\TypeParser ;
2023-07-14 16:34:52 +02:00
use function Amp\File\read ;
2019-12-14 16:47:04 +01:00
2022-12-08 20:16:40 +01:00
chdir ( $d = __DIR__ . '/..' );
2019-10-29 22:00:21 +01:00
2023-08-13 16:57:42 +02:00
`git checkout src/InternalDoc.php` ;
2017-01-02 19:50:37 +01:00
require 'vendor/autoload.php' ;
2019-10-28 22:39:23 +01:00
2023-06-24 19:08:30 +02:00
require 'tools/translator.php' ;
2023-05-27 18:35:31 +02:00
copy ( 'https://rpc.madelineproto.xyz/v3.json' , 'src/v3.json' );
2023-01-25 16:32:48 +01:00
Magic :: start ( light : false );
2020-09-24 20:49:34 +02:00
Logger :: constructorFromSettings ( new SettingsLogger );
2020-06-16 17:52:55 +02:00
$logger = Logger :: $default ;
2022-12-08 20:16:40 +01:00
set_error_handler ([ '\danog\MadelineProto\Exception' , 'ExceptionErrorHandler' ]);
2016-12-19 16:56:52 +01:00
2020-06-16 17:52:55 +02:00
$logger -> logger ( 'Merging constructor localization...' , Logger :: NOTICE );
mergeExtracted ();
2016-12-19 16:56:52 +01:00
2020-06-16 17:52:55 +02:00
$logger -> logger ( 'Loading schemas...' , Logger :: NOTICE );
$schemas = loadSchemas ();
$logger -> logger ( 'Upgrading layer...' , Logger :: NOTICE );
$layer = maxLayer ( $schemas );
layerUpgrade ( $layer );
2020-03-06 13:09:52 +01:00
2020-10-01 18:02:54 +02:00
$logger -> logger ( " Initing docs (layer $layer )... " , Logger :: NOTICE );
2017-01-02 19:50:37 +01:00
$docs = [
[
2023-08-13 16:21:59 +02:00
'TL' => ( new TLSchema ) -> setMTProtoSchema ( '' ) -> setAPISchema ( " $d /schemas/TL_telegram_v $layer .tl " ) -> setSecretSchema ( " $d /schemas/TL_secret.tl " ),
2020-03-06 13:09:52 +01:00
'title' => " MadelineProto API documentation (layer $layer ) " ,
'description' => " MadelineProto API documentation (layer $layer ) " ,
2019-10-29 22:00:21 +01:00
'output_dir' => " $d /docs/docs/API_docs " ,
2020-06-16 17:52:55 +02:00
'template' => " $d /docs/template " ,
2017-01-07 12:40:51 +01:00
'readme' => false ,
2017-01-02 19:50:37 +01:00
],
];
2017-01-03 00:28:51 +01:00
2020-06-16 17:52:55 +02:00
$logger -> logger ( 'Creating annotations...' , Logger :: NOTICE );
2019-12-14 16:47:04 +01:00
$doc = new \danog\MadelineProto\AnnotationsBuilder (
$logger ,
2022-05-01 20:17:16 +02:00
$docs [ 0 ],
2019-12-14 16:47:04 +01:00
[
'API' => API :: class ,
2023-11-11 16:55:29 +01:00
'MTProto' => MTProto :: class ,
2019-12-14 16:47:04 +01:00
],
'danog\\MadelineProto'
);
2019-10-29 22:00:21 +01:00
$doc -> mkAnnotations ();
2017-01-22 17:40:56 +01:00
2020-06-16 17:52:55 +02:00
$logger -> logger ( 'Creating docs...' , Logger :: NOTICE );
2017-01-02 19:50:37 +01:00
foreach ( $docs as $settings ) {
2018-04-19 19:56:52 +02:00
$doc = new \danog\MadelineProto\DocsBuilder ( $logger , $settings );
2019-10-29 22:00:21 +01:00
$doc -> mkDocs ();
2016-12-19 16:56:52 +01:00
}
2019-03-08 15:16:58 +01:00
2022-12-08 20:16:40 +01:00
chdir ( __DIR__ . '/..' );
2019-03-08 15:16:58 +01:00
2020-06-16 17:52:55 +02:00
$logger -> logger ( 'Fixing readme...' , Logger :: NOTICE );
2019-03-08 15:16:58 +01:00
$orderedfiles = [];
$order = [
'CREATING_A_CLIENT' ,
'LOGIN' ,
'FEATURES' ,
'REQUIREMENTS' ,
2023-05-31 12:23:26 +02:00
'DOCKER' ,
2019-03-08 15:16:58 +01:00
'INSTALLATION' ,
2023-05-26 17:54:42 +02:00
'BROADCAST' ,
2019-03-08 15:16:58 +01:00
'UPDATES' ,
2023-07-14 16:34:52 +02:00
'FILTERS' ,
'PLUGINS' ,
2021-09-05 19:33:22 +02:00
'DATABASE' ,
2019-03-08 15:16:58 +01:00
'SETTINGS' ,
'SELF' ,
'EXCEPTIONS' ,
'FLOOD_WAIT' ,
'LOGGING' ,
'CALLS' ,
'FILES' ,
'CHAT_INFO' ,
'DIALOGS' ,
'INLINE_BUTTONS' ,
'SECRET_CHATS' ,
'PROXY' ,
2019-12-30 20:41:06 +01:00
'ASYNC' ,
2023-06-25 16:59:56 +02:00
'FAQ' ,
2023-08-20 19:22:51 +02:00
'UPGRADING' ,
2019-03-08 15:16:58 +01:00
'USING_METHODS' ,
'CONTRIB' ,
2019-06-04 14:55:58 +02:00
'TEMPLATES' ,
2019-03-08 15:16:58 +01:00
];
$index = '' ;
2022-12-08 20:16:40 +01:00
$files = glob ( 'docs/docs/docs/*md' );
2019-03-08 15:16:58 +01:00
foreach ( $files as $file ) {
2022-12-08 20:16:40 +01:00
$base = basename ( $file , '.md' );
2019-10-28 19:48:59 +01:00
if ( $base === 'UPDATES_INTERNAL' ) {
continue ;
}
2023-11-11 16:55:29 +01:00
$key = array_search ( $base , $order , true );
2019-03-08 15:16:58 +01:00
if ( $key !== false ) {
$orderedfiles [ $key ] = $file ;
}
}
2022-12-08 20:16:40 +01:00
ksort ( $orderedfiles );
2023-07-14 16:34:52 +02:00
2024-04-06 19:21:12 +02:00
/** @internal */
function getSummary ( string $phpdoc ) : string
{
$lexer = new Lexer ();
$constExprParser = new ConstExprParser ();
$typeParser = new TypeParser ( $constExprParser );
$parser = new PhpDocParser (
$typeParser ,
$constExprParser ,
textBetweenTagsBelongsToDescription : true
);
foreach ( $parser -> parse ( new TokenIterator ( $lexer -> tokenize ( $phpdoc ))) -> children as $t ) {
if ( $t instanceof PhpDocTextNode ) {
return explode ( " \n " , $t -> text )[ 0 ];
}
}
return '' ;
}
2023-07-14 16:34:52 +02:00
/** @internal */
function printTypes ( array $types , string $type ) : string
{
$phpdoc = PhpDoc :: fromNamespace ();
$data = '' ;
foreach ( $types as $class ) {
2023-07-14 18:29:20 +02:00
if ( $type === 'concretefilters' && $class === Update :: class ) {
continue ;
}
2023-07-14 16:34:52 +02:00
$refl = new ReflectionClass ( $class );
$link = " https://docs.madelineproto.xyz/PHP/ " . str_replace ( '\\' , '/' , $class ) . '.html' ;
2023-08-31 18:02:11 +02:00
if ( ! $refl -> getDocComment ()) {
throw new AssertionError ( " No documentation for $class ! " );
}
2024-04-06 19:21:12 +02:00
$f = getSummary ( $refl -> getDocComment ());
2023-07-14 16:34:52 +02:00
if ( $refl -> hasMethod ( '__construct' )) {
$c = $refl -> getMethod ( '__construct' );
if ( $c -> getParameters () && $type === 'attributefilters' ) {
$c = new MethodDoc ( $phpdoc , $c );
$c = $c -> getSignature ();
$class .= str_replace ([ '__construct' , '\danog\MadelineProto\EventHandler\Filter\\' ], '' , $c );
}
}
$data .= " * [ $class »]( $link ) - $f\n " ;
if ( $type !== 'concretefilters' ) {
continue ;
}
$data .= " * [Full property list »]( $link #properties) \n " ;
2023-07-14 18:29:20 +02:00
$data .= " * [Full bound method list »]( $link #method-list) \n " ;
2023-07-14 16:34:52 +02:00
}
return $data ;
}
2019-03-08 15:16:58 +01:00
foreach ( $orderedfiles as $key => $filename ) {
2023-07-14 16:34:52 +02:00
$lines = file_get_contents ( $filename );
2023-11-11 16:55:29 +01:00
$lines = preg_replace_callback ( '/\<\!--\s+cut_here\s+(\S+)\s+-->.*\<\!--\s+cut_here_end\s+\1\s+--\>/sim' , static function ( $matches ) {
2023-07-14 16:34:52 +02:00
[, $match ] = $matches ;
if ( $match === " concretefilters " ) {
2023-08-20 14:33:38 +02:00
$result = ClassFinder :: getClassesInNamespace (
\danog\MadelineProto :: class ,
2023-07-14 16:34:52 +02:00
ClassFinder :: RECURSIVE_MODE | ClassFinder :: ALLOW_ALL
2023-08-20 14:33:38 +02:00
);
$result [] = ServiceMessage :: class ;
$result = array_filter (
$result ,
2023-11-11 16:55:29 +01:00
static fn ( $class ) => is_subclass_of ( $class , Update :: class )
2023-08-20 14:33:38 +02:00
);
sort ( $result );
2023-07-14 16:34:52 +02:00
$data = printTypes ( $result , $match );
} elseif ( $match === " simplefilters " ) {
$result = ClassFinder :: getClassesInNamespace (
\danog\MadelineProto\EventHandler\SimpleFilter :: class ,
ClassFinder :: RECURSIVE_MODE | ClassFinder :: ALLOW_ALL
);
$data = printTypes ( $result , $match );
} elseif ( $match === " attributefilters " ) {
$result = ClassFinder :: getClassesInNamespace (
\danog\MadelineProto\EventHandler\Filter :: class ,
ClassFinder :: RECURSIVE_MODE | ClassFinder :: ALLOW_ALL
);
2023-11-11 16:55:29 +01:00
$result = array_filter ( $result , static fn ( string $class ) => ( new ReflectionClass ( $class )) -> getAttributes ());
2023-07-14 16:34:52 +02:00
$data = printTypes ( $result , $match );
2023-10-26 19:39:23 +02:00
} elseif ( $match === " plugins " ) {
$result = ClassFinder :: getClassesInNamespace (
\danog\MadelineProto\EventHandler\Plugin :: class ,
ClassFinder :: RECURSIVE_MODE | ClassFinder :: ALLOW_ALL
);
$data = printTypes ( $result , $match );
2023-07-14 16:34:52 +02:00
} elseif ( $match === " mtprotofilters " ) {
2023-07-14 18:29:20 +02:00
$data = " * onUpdateCustomEvent: Receives messages sent to the event handler from an API instance using the [`sendCustomEvent` »](https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#sendcustomevent-mixed-payload-void) method. \n " ;
$data .= " * onAny: Catch-all filter, if defined catches all updates that aren't catched by any other filter. \n " ;
$data .= " * [onUpdateBroadcastProgress »](https://docs.madelineproto.xyz/docs/BROADCAST.html#get-progress): Used to receive updates to an in-progress [message broadcast »](https://docs.madelineproto.xyz/docs/BROADCAST.html) " ;
2023-07-14 16:34:52 +02:00
$TL = new TL ( null );
$TL -> init ( new TLSchema );
foreach ( $TL -> getConstructors () -> by_id as $cons ) {
if ( $cons [ 'type' ] !== 'Update' ) {
continue ;
}
$predicate = 'on' . ucfirst ( $cons [ 'predicate' ]);
$predicateRaw = $cons [ 'predicate' ];
$desc = explode ( " \n " , Lang :: $lang [ 'en' ][ " object_ $predicateRaw " ])[ 0 ];
$desc = str_replace ([ '](../' , '.md' ], [ '](https://docs.madelineproto.xyz/API_docs/' , '.html' ], $desc );
$data .= " * [ $predicate »](https://docs.madelineproto.xyz/API_docs/constructors/ $predicateRaw .html) - $desc\n " ;
}
} else {
$data = read ( $match );
$data = " ```php \n { $data } \n ``` " ;
}
return " <!-- cut_here $match --> \n \n $data\n\n <!-- cut_here_end $match --> " ;
}, $lines );
$lines = explode ( " \n " , $lines );
2022-12-08 20:16:40 +01:00
while ( end ( $lines ) === '' || strpos ( end ( $lines ), 'Next' )) {
unset ( $lines [ count ( $lines ) - 1 ]);
2019-03-08 15:16:58 +01:00
}
if ( $lines [ 0 ] === '---' ) {
2022-12-08 20:16:40 +01:00
array_shift ( $lines );
2019-03-08 15:16:58 +01:00
while ( $lines [ 0 ] !== '---' ) {
2022-12-08 20:16:40 +01:00
array_shift ( $lines );
2019-03-08 15:16:58 +01:00
}
2022-12-08 20:16:40 +01:00
array_shift ( $lines );
2019-03-08 15:16:58 +01:00
}
2023-04-22 20:22:17 +02:00
2022-12-08 20:16:40 +01:00
preg_match ( '|^# (.*)|' , $lines [ 0 ], $matches );
2019-03-08 15:16:58 +01:00
$title = $matches [ 1 ];
2022-12-08 20:16:40 +01:00
$description = str_replace ( '"' , " ' " , Tools :: toString ( $lines [ 2 ]));
2019-03-08 15:16:58 +01:00
2022-12-08 20:16:40 +01:00
array_unshift (
2022-05-01 20:17:16 +02:00
$lines ,
'---' ,
'title: "' . $title . '"' ,
'description: "' . $description . '"' ,
'nav_order: ' . ( $key + 4 ),
'image: https://docs.madelineproto.xyz/favicons/android-chrome-256x256.png' ,
'---'
);
2019-03-08 15:16:58 +01:00
if ( isset ( $orderedfiles [ $key + 1 ])) {
2022-12-08 20:16:40 +01:00
$nextfile = 'https://docs.madelineproto.xyz/docs/' . basename ( $orderedfiles [ $key + 1 ], '.md' ) . '.html' ;
$lines [ count ( $lines )] = " \n <a href= \" $nextfile\ " > Next section </ a > " ;
2019-03-08 15:16:58 +01:00
} else {
2022-12-08 20:16:40 +01:00
$lines [ count ( $lines )] = " \n <a href= \" https://docs.madelineproto.xyz/#very-complex-and-complete-examples \" >Next section</a> " ;
2019-03-08 15:16:58 +01:00
}
2022-12-08 20:16:40 +01:00
file_put_contents ( $filename , implode ( " \n " , $lines ));
2019-03-08 15:16:58 +01:00
2022-12-08 20:16:40 +01:00
$file = file_get_contents ( $filename );
2019-03-08 15:16:58 +01:00
2022-12-08 20:16:40 +01:00
preg_match_all ( '|( *)\* \[(.*)\]\((.*)\)|' , $file , $matches );
$file = 'https://docs.madelineproto.xyz/docs/' . basename ( $filename , '.md' ) . '.html' ;
2023-08-13 13:35:46 +02:00
$index .= " * [ $title ]( $file ) - $description\n " ;
2022-12-08 20:16:40 +01:00
if ( basename ( $filename ) !== 'FEATURES.md' ) {
2019-03-08 15:16:58 +01:00
foreach ( $matches [ 1 ] as $key => $match ) {
$spaces = " $match " ;
$name = $matches [ 2 ][ $key ];
2021-09-05 20:51:29 +02:00
if ( $matches [ 3 ][ $key ][ 0 ] === '#' ) {
$url = $file . $matches [ 3 ][ $key ];
2022-12-08 20:16:40 +01:00
} elseif ( substr ( $matches [ 3 ][ $key ], 0 , 3 ) === '../' ) {
$url = 'https://docs.madelineproto.xyz/' . str_replace ( '.md' , '.html' , substr ( $matches [ 3 ][ $key ], 3 ));
2023-07-14 16:34:52 +02:00
if ( basename ( $filename ) === 'FILTERS.md' ) {
continue ;
}
2021-09-05 20:51:29 +02:00
} else {
$url = $matches [ 3 ][ $key ];
2023-07-14 16:34:52 +02:00
if ( basename ( $filename ) === 'FILTERS.md' ) {
continue ;
}
2021-09-05 20:51:29 +02:00
}
2023-07-14 18:29:20 +02:00
if ( basename ( $filename ) === 'UPDATES.md' && str_starts_with ( $url , 'https://docs.madelineproto.xyz/PHP/danog/MadelineProto/EventHandler' )) {
continue ;
}
2019-03-08 15:16:58 +01:00
$index .= " $spaces * [ $name ]( $url ) \n " ;
if ( $name === 'FULL API Documentation with descriptions' ) {
2019-06-04 14:55:58 +02:00
$spaces .= ' ' ;
2022-12-08 20:16:40 +01:00
preg_match_all ( '|\* (.*)|' , file_get_contents ( 'docs/docs/API_docs/methods/index.md' ), $smatches );
2019-03-08 15:16:58 +01:00
foreach ( $smatches [ 1 ] as $key => $match ) {
2022-12-08 20:16:40 +01:00
if ( str_contains ( $match , 'You cannot use this method directly' )) {
2022-05-01 20:17:16 +02:00
continue ;
}
2023-06-13 21:30:02 +02:00
if ( ! str_contains ( $match , 'href="https://docs.madelineproto.xyz' )) {
$match = str_replace ( 'href="' , 'href="https://docs.madelineproto.xyz/API_docs/methods/' , $match );
}
2019-03-08 15:16:58 +01:00
$index .= " $spaces * " . $match . " \n " ;
}
}
}
}
}
2020-06-16 17:52:55 +02:00
$logger -> logger ( 'Fixing readme...' , Logger :: NOTICE );
2022-12-08 20:16:40 +01:00
$readme = explode ( '## ' , file_get_contents ( 'README.md' ));
2019-03-08 15:16:58 +01:00
foreach ( $readme as & $section ) {
2022-12-08 20:16:40 +01:00
if ( explode ( " \n " , $section )[ 0 ] === 'Documentation' ) {
2019-03-08 15:16:58 +01:00
$section = " Documentation \n \n " . $index . " \n " ;
}
}
2022-12-08 20:16:40 +01:00
$readme = implode ( '## ' , $readme );
2019-03-08 15:16:58 +01:00
2022-12-08 20:16:40 +01:00
file_put_contents ( 'README.md' , $readme );
file_put_contents ( 'docs/docs/index.md' , ' ---
2022-05-01 19:59:07 +02:00
title : MadelineProto
2019-03-08 15:16:58 +01:00
description : PHP client / server for the telegram MTProto protocol ( a better tg - cli )
2022-05-01 20:17:16 +02:00
nav_order : 1
2019-03-08 15:16:58 +01:00
image : https :// docs . madelineproto . xyz / favicons / android - chrome - 256 x256 . png
---
' . $readme );
2022-05-01 20:17:16 +02:00
2023-05-26 17:54:42 +02:00
include 'phpdoc.php' ;