PHP 8 Library for Gemini Protocol
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
yggverse f12ff02616 escape all url entities 8 months ago
src escape all url entities 8 months ago
.gitignore add ASCII table support 11 months ago
LICENSE Initial commit 11 months ago
README.md implement gemtext code format 9 months ago
composer.json add ASCII table support 11 months ago

README.md

gemini-php

PHP 8 Library for Gemini Protocol

Usage

composer require yggverse/gemini

Client

PHP interface for Gemini protocol queries by TLS socket connection

Request

$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

$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

$request->setResolvedHost(
    '68.133.1.71'
)
  • to resolve network address with PHP, take a look on the 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

var_dump(
    $request->getResponse()
);

Request::getOptions

Request::setOptions

$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

$response = new \Yggverse\Gemini\Client\Response(
    $request->getResponse()
);

Response::setCode

Response::getCode

Response::setMeta

Response::getMeta

Response::setBody

Response::getBody

var_dump(
    $response->getBody()
);

Gemtext

Object-oriented API for Gemtext

Body

Basic methods to work with text/gemini documents

$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

var_dump(
    $body->getLinks() // returns array of links (with line number in key)
);

Find context links by protocol as argument, gemini by default

var_dump(
    $body->findLinks('http') // returns array of http links only (with line number in key)
);

Body::skipTags

Strip gemini tags from Gemini document

var_dump(
    $body->skipTags() // strip all tags
);

var_dump(
    $body->skipTags(
        [ // 1- and 2- level headers only
            "##",
            "###"
        ]
    )
);

Inline links parser.

Allows to extract address, date with timestamp and alt text from link line given

foreach ($body->getLinks() as $line)
{
    $link = new \Yggverse\Gemini\Gemtext\Link(
        $line
    );

    var_dump(
        $link->getAddress()
    );

    var_dump(
        $link->getAlt()
    );
}

This method also validates time format and returns the unix timestamp as linked argument

var_dump(
    $link->getDate(
        $timestamp // get unix time from this variable
    )
);

var_dump(
    $timestamp
);

Pango

Converter for GTK/Pango format

Pango::fromGemtext

$pango = \Yggverse\Gemini\Pango::fromGemtext(
    $gemtext
);

Pango::fromGemtextBody

$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 - DokuWiki Satellite for Gemini Protocol

Reader

Read DokuWiki and convert to Gemini

$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)

echo $reader->setRule(
    '/subject/ui',
    'replacement'
);

Reader::getMacroses

Reader::setMacroses

Reader::getMacros

Reader::setMacros

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!

echo $reader->toGemini(
    file_get_contents(
        '/host/data/pages/index.txt'
    )
);

Reader::getH1

Get document title

$gemini = $reader->toGemini(
    file_get_contents(
        '/host/data/pages/index.txt'
    )
);

echo $reader->getH1(
    $gemini
);

Get document links

$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

$filesystem = new \Yggverse\Gemini\Dokuwiki\Filesystem(
    '/host/data' // storage location
);

Filesystem::getList

Return simple array of all files in storage

var_dump (
    $filesystem->getList(
        'hello:world'
    )
);

Filesystem::getTree

Return all files under the storage folder in tree format

var_dump (
    $filesystem->getTree(
        'hello:world'
    )
);

Filesystem::getPagePathsByPath

Return pages under the given data directory

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

var_dump (
    $filesystem->getPagePathByUri(
        'hello:world'
    )
);

Filesystem::getDirectoryUriByPath

Filesystem::getPageUriByPath

Return page URI in dokuwiki:format

var_dump (
    $filesystem->getPageUriByPath(
        '/full/path/to/page.txt'
    )
);

Filesystem::getMediaPathByUri

Return absolute path to stored media file

var_dump (
    $filesystem->getMediaPathByUri(
        'hello:world'
    )
);

Filesystem::getMimeByPath

Return file MIME if path match storage item

var_dump (
    $filesystem->getMimeByPath(
        '/full/path/to/page.txt'
    )
);

Filesystem::getDataByPath

Return file content if path match storage item

var_dump (
    $filesystem->getDataByPath(
        '/full/path/to/page.txt'
    )
);

Filesystem::isPath

Check path exist and match storage item

var_dump (
    $filesystem->isPath(
        '/full/path/to/page.txt'
    )
);

Helper

Useful methods to minify controller codebase

$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

var_dump (
    $helper->getChildrenSectionLinksByUri(
        'hello:world'
    )
);

Helper::getChildrenPageLinksByUri

Return simple array of children page links in Gemini format

var_dump (
    $helper->getChildrenPageLinksByUri(
        'hello:world'
    )
);

Helper::getPageLinkByPath

Return page link (that contain document name) in Gemini format

var_dump (
    $helper->getPageLinkByPath(
        $filesystem->getPagePathByUri(
            'hello:world'
        )
    )
);

Integrations