# gemini-php PHP 8 Library for [Gemini Protocol](https://geminiprotocol.net) ## Usage ``` composer require yggverse/gemini ``` ## Client PHP interface for Gemini protocol queries by TLS socket connection ### Request ``` php $request = new \Yggverse\Gemini\Client\Request( 'gemini://yggverse.cities.yesterweb.org:1965/index.gmi' ); ``` **Resolved request (SNI)** For direct connection provide resolved IP as the second argument ``` php $request = new \Yggverse\Gemini\Client\Request( 'gemini://yggverse.cities.yesterweb.org:1965/index.gmi' // target URL '68.133.1.71' // resolved IP, skip to use system-wide resolver ); ``` Alternatively, use `setResolvedHost` method of `Request` object before `getResponse` #### Request::setResolvedHost ``` php $request->setResolvedHost( '68.133.1.71' ) ``` * to resolve network address with PHP, take a look on the [net-php](https://github.com/YGGverse/net-php) library! #### Request::getResolvedHost Get resolved host back #### Request::setHost #### Request::getHost #### Request::setPort #### Request::getPort #### Request::setPath #### Request::getPath #### Request::setQuery #### Request::getQuery #### Request::getResponse Execute requested URL and return raw response ``` php var_dump( $request->getResponse() ); ``` #### Request::getOptions #### Request::setOptions ``` php $request = new \Yggverse\Gemini\Client\Request( 'gemini://yggverse.cities.yesterweb.org', '68.133.1.71' // make direct request to the resolved host ); $request->setOptions( [ 'ssl' => [ 'peer_name' => 'yggverse.cities.yesterweb.org', // SNI 'verify_peer' => false, 'verify_peer_name' => false ] ] ); ``` ### Response This class provides additional features for the raw response operations ``` php $response = new \Yggverse\Gemini\Client\Response( $request->getResponse() ); ``` #### Response::setCode #### Response::getCode #### Response::setMeta #### Response::getMeta #### Response::setBody #### Response::getBody ``` php var_dump( $response->getBody() ); ``` ## Gemtext Object-oriented API for Gemtext **Deprecated and will be removed in future releases! Use [gemtext-php](https://github.com/YGGverse/gemtext-php) instead.** ### Body Basic methods to work with `text/gemini` documents ``` php $body = new \Yggverse\Gemini\Gemtext\Body( $response->getBody() // gemtext body from client response or .gmi file content ); ``` #### Body::getLines #### Body::getLine #### Body::getH1 #### Body::getH2 #### Body::getH3 #### Body::getQuote #### Body::getCode #### Body::getLinks ``` php var_dump( $body->getLinks() // returns array of links (with line number in key) ); ``` #### Body::findLinks Find context links by protocol as argument, `gemini` by default ``` php var_dump( $body->findLinks('http') // returns array of http links only (with line number in key) ); ``` #### Body::skipTags Strip gemini tags from Gemini document ``` php var_dump( $body->skipTags() // strip all tags ); var_dump( $body->skipTags( [ // 1- and 2- level headers only "##", "###" ] ) ); ``` ### Link Inline links parser. Allows to extract address, date with timestamp and alt text from link line given ``` php foreach ($body->getLinks() as $line) { $link = new \Yggverse\Gemini\Gemtext\Link( $line ); var_dump( $link->getAddress() ); var_dump( $link->getAlt() ); } ``` #### Link::getAddress #### Link::getDate This method also validates time format and returns the unix timestamp as linked argument ``` php var_dump( $link->getDate( $timestamp // get unix time from this variable ) ); var_dump( $timestamp ); ``` #### Link::getAlt ## GTK3 ### Pango Converter to GTK3-compatible Pango format #### Pango::fromGemtext ``` php $pango = \Yggverse\Gemini\Pango::fromGemtext( $gemtext ); ``` #### Pango::fromGemtextBody ``` php $pango = \Yggverse\Gemini\Pango::fromGemtextBody( new \Yggverse\Gemini\Gemtext\Body( $gemtext ) ); ``` ## DokuWiki Toolkit provides DokuWiki API for Gemini. Allows to simple deploy new apps or make existing website mirror ### Examples * [β-Doku](https://github.com/YGGverse/bdoku) - DokuWiki Satellite for Gemini Protocol ### Reader Read DokuWiki and convert to Gemini ``` php $reader = new \Yggverse\Gemini\Dokuwiki\Reader( // optional regex rule set array ); ``` #### Reader::getRules #### Reader::setRules #### Reader::getRule #### Reader::setRule Get or change existing regex rule (or just skip by using build-in set) ``` php echo $reader->setRule( '/subject/ui', 'replacement' ); ``` #### Reader::getMacroses #### Reader::setMacroses #### Reader::getMacros #### Reader::setMacros ``` php echo $reader->setMacros( '~my-macros-key~', '~my-macros-value~', ); ``` #### Reader::toGemini Convert DokuWiki text to Gemini markup As wiki has lot of inline links, to make converted document well-readable, this method does not replace links with new line `=>` macros, but uses inline context: `Name ( URL )`. This model useful with `Reader::getLinks` method, that for example appends all those related links to the document footer. If you don't like this implementation, feel free to change it by `Reader::setRule` method! ``` php echo $reader->toGemini( file_get_contents( '/host/data/pages/index.txt' ) ); ``` #### Reader::getH1 Get document title ``` php $gemini = $reader->toGemini( file_get_contents( '/host/data/pages/index.txt' ) ); echo $reader->getH1( $gemini ); ``` #### Reader::getLinks Get document links ``` php $gemini = $reader->toGemini( file_get_contents( '/host/data/pages/index.txt' ) ); echo $reader->getLinks( $gemini ); ``` ### Filesystem Provides methods for simple and secure interaction with DokuWiki file storage ``` php $filesystem = new \Yggverse\Gemini\Dokuwiki\Filesystem( '/host/data' // storage location ); ``` #### Filesystem::getList Return simple array of all files in storage ``` php var_dump ( $filesystem->getList( 'hello:world' ) ); ``` #### Filesystem::getTree Return all files under the storage folder in tree format ``` php var_dump ( $filesystem->getTree( 'hello:world' ) ); ``` #### Filesystem::getPagePathsByPath Return pages under the given data directory ``` php var_dump ( $filesystem->getPagePathsByPath( // absolute path to target data directory (e.g. Filesystem::getDirectoryPathByUri) ) ); ``` #### Filesystem::getDirectoryPathByUri #### Filesystem::getPagePathByUri Return absolute path to stored page file ``` php var_dump ( $filesystem->getPagePathByUri( 'hello:world' ) ); ``` #### Filesystem::getDirectoryUriByPath #### Filesystem::getPageUriByPath Return page URI in `dokuwiki:format` ``` php var_dump ( $filesystem->getPageUriByPath( '/full/path/to/page.txt' ) ); ``` #### Filesystem::getMediaPathByUri Return absolute path to stored media file ``` php var_dump ( $filesystem->getMediaPathByUri( 'hello:world' ) ); ``` #### Filesystem::getMimeByPath Return file MIME if path match storage item ``` php var_dump ( $filesystem->getMimeByPath( '/full/path/to/page.txt' ) ); ``` #### Filesystem::getDataByPath Return file content if path match storage item ``` php var_dump ( $filesystem->getDataByPath( '/full/path/to/page.txt' ) ); ``` #### Filesystem::isPath Check path exist and match storage item ``` php var_dump ( $filesystem->isPath( '/full/path/to/page.txt' ) ); ``` ### Helper Useful methods to minify controller codebase ``` php $helper = new \Yggverse\Gemini\Dokuwiki\Helper( new \Yggverse\Gemini\Dokuwiki\Filesystem(), new \Yggverse\Gemini\Dokuwiki\Reader() ); ``` #### Helper::getChildrenSectionLinksByUri Return simple array of children section links in Gemini format ``` php var_dump ( $helper->getChildrenSectionLinksByUri( 'hello:world' ) ); ``` #### Helper::getChildrenPageLinksByUri Return simple array of children page links in Gemini format ``` php var_dump ( $helper->getChildrenPageLinksByUri( 'hello:world' ) ); ``` #### Helper::getPageLinkByPath Return page link (that contain document name) in Gemini format ``` php var_dump ( $helper->getPageLinkByPath( $filesystem->getPagePathByUri( 'hello:world' ) ) ); ``` ## Integrations * [β-Doku is DokuWiki Satellite for Gemini Protocol](https://github.com/YGGverse/bdoku) * [Yo! Crawler for different networks](https://github.com/YGGverse/Yo/tree/gemini) * [Yoda - PHP-GTK browser for Gemini Protocol](https://github.com/YGGverse/Yoda)