├── temp └── .gitkeep ├── htmlhelp ├── exclude.txt ├── make_chm.bat ├── suppfiles │ ├── html │ │ ├── _atw.gif │ │ ├── _body.gif │ │ ├── _code.gif │ │ ├── _note.gif │ │ ├── _pixel.gif │ │ ├── _google.gif │ │ ├── _warning.gif │ │ ├── _subheader.gif │ │ ├── _masterheader.jpg │ │ ├── _skin_hi.js │ │ ├── _skin_lo.js │ │ └── _function.html │ ├── skins │ │ ├── phpZ │ │ │ ├── logo.gif │ │ │ ├── skin.js │ │ │ ├── style.css │ │ │ ├── background.gif │ │ │ ├── icn_goTOC.gif │ │ │ ├── icn_next.gif │ │ │ ├── icn_prev.gif │ │ │ ├── white_fade.gif │ │ │ ├── icn_bugOnPage.gif │ │ │ ├── header_background.gif │ │ │ ├── icn_goToFunctionRef.gif │ │ │ ├── icn_thisPageOnline.gif │ │ │ ├── tabs_corner_active.gif │ │ │ ├── tabs_corner_inactive.gif │ │ │ ├── header_green_background.gif │ │ │ ├── tabs_background_inactive.gif │ │ │ ├── tab_button_pageNotes_active.gif │ │ │ ├── tab_button_pageText_active.gif │ │ │ ├── tab_button_pageNotes_inactive.gif │ │ │ └── tab_button_pageText_inactive.gif │ │ ├── HeaderNostalgia │ │ │ ├── phpdoc_menu.png │ │ │ ├── phpdoc_php.png │ │ │ ├── phpdoc_midback.png │ │ │ ├── phpdoc_upback.png │ │ │ ├── phpdoc_bellowmenu.png │ │ │ └── phpdoc_bottomback.png │ │ └── GreenLinks │ │ │ └── skin.js │ ├── quickref │ │ ├── php_manual.ico │ │ └── php_quickref.hta │ ├── prefs │ │ ├── php_manual_prefs.exe │ │ ├── php_manual_prefs.js │ │ └── context.ini │ └── notes │ │ ├── _style.css │ │ ├── _index.html │ │ └── _notes_script.js ├── make-xchm ├── mirrors_ini.php ├── split_notes.php ├── TODO.txt ├── README.txt └── local_vars.php.src ├── scripts ├── docgen │ ├── docgen.bat │ ├── versions.tpl │ ├── constants.tpl │ ├── configure.tpl │ ├── reference.tpl │ ├── examples.tpl │ ├── book.tpl │ ├── ini.tpl │ ├── setup.tpl │ ├── function.tpl │ ├── method.tpl │ ├── constructor.tpl │ ├── mapping.tpl │ └── class.tpl ├── translation │ ├── .gitignore │ ├── libqa │ │ ├── SyncFileItem.php │ │ ├── all.php │ │ ├── SyncFileList.php │ │ └── ArgvParser.php │ ├── configure.php │ ├── qaxml-revtag.php │ ├── lib │ │ ├── all.php │ │ ├── CacheUtil.php │ │ ├── CacheFile.php │ │ ├── QaFileInfo.php │ │ ├── RevcheckIgnore.php │ │ ├── RevcheckFileList.php │ │ ├── RevcheckFileItem.php │ │ ├── XmlUtil.php │ │ ├── OutputIgnoreArgv.php │ │ └── RevcheckData.php │ ├── qarvt.php │ ├── qaxml-pi.php │ ├── qaxml.e.php │ ├── qaxml-ws.php │ ├── qaxml.w.php │ ├── qaxml-attributes.php │ ├── qaxml.p.php │ ├── qaxml.a.php │ └── qaxml-entities.php ├── include │ ├── lib-misc.inc.php │ └── lib-translations.inc.php ├── helpers │ └── phpdoc-completion.sh ├── check-underdocumented.php ├── notes_extract.php ├── qa │ └── check-missing-initializers.php ├── en.pws ├── grep-files.php ├── mk_ini_set_table.sh ├── xml-check.php ├── build-chms-history.php ├── aspell.php ├── orphan_notes.php ├── gen-phpdoc-tz-list.php ├── script-skel.php └── fetch-chms.php ├── docbook ├── jing.jar ├── docbook-v5.2-os │ ├── dbits.nvdl │ ├── docbook.nvdl │ └── assembly.nvdl └── JING_LICENSE ├── chm ├── make_chm_spc.gif ├── manual.chm.xml ├── make_chm_style.css ├── make_chm.bat └── common.php ├── .github ├── dependabot.yml └── workflows │ └── integrate.yaml ├── .gitignore ├── README.md ├── docs ├── tools.md ├── public-builds.md ├── toc.md ├── local-web-setup.md ├── tags-and-entities.md ├── README.md ├── joining.md ├── user-notes.md ├── editing.md ├── contributing.md ├── faq.md └── structure.md ├── funcindex.xml ├── CODEOWNERS ├── skeletons ├── versions.xml ├── book.xml ├── reference.xml ├── configure.xml ├── constants.xml ├── examples.xml ├── setup.xml ├── ini.xml └── exceptionname.xml └── LICENSE /temp/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /htmlhelp/exclude.txt: -------------------------------------------------------------------------------- 1 | CVS -------------------------------------------------------------------------------- /htmlhelp/make_chm.bat: -------------------------------------------------------------------------------- 1 | @php -f make_chm.php -------------------------------------------------------------------------------- /scripts/docgen/docgen.bat: -------------------------------------------------------------------------------- 1 | @echo OFF 2 | REM $Id$ 3 | 4 | @php docgen.php %* -------------------------------------------------------------------------------- /docbook/jing.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/doc-base/master/docbook/jing.jar -------------------------------------------------------------------------------- /scripts/translation/.gitignore: -------------------------------------------------------------------------------- 1 | # Persistent data shared between scripts 2 | .cache/ 3 | -------------------------------------------------------------------------------- /chm/make_chm_spc.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/doc-base/master/chm/make_chm_spc.gif -------------------------------------------------------------------------------- /htmlhelp/suppfiles/html/_atw.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/doc-base/master/htmlhelp/suppfiles/html/_atw.gif -------------------------------------------------------------------------------- /htmlhelp/suppfiles/html/_body.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/doc-base/master/htmlhelp/suppfiles/html/_body.gif -------------------------------------------------------------------------------- /htmlhelp/suppfiles/html/_code.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/doc-base/master/htmlhelp/suppfiles/html/_code.gif -------------------------------------------------------------------------------- /htmlhelp/suppfiles/html/_note.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/doc-base/master/htmlhelp/suppfiles/html/_note.gif -------------------------------------------------------------------------------- /htmlhelp/suppfiles/html/_pixel.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/doc-base/master/htmlhelp/suppfiles/html/_pixel.gif -------------------------------------------------------------------------------- /htmlhelp/suppfiles/html/_google.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/doc-base/master/htmlhelp/suppfiles/html/_google.gif -------------------------------------------------------------------------------- /htmlhelp/suppfiles/html/_warning.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/doc-base/master/htmlhelp/suppfiles/html/_warning.gif -------------------------------------------------------------------------------- /htmlhelp/suppfiles/html/_subheader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/doc-base/master/htmlhelp/suppfiles/html/_subheader.gif -------------------------------------------------------------------------------- /htmlhelp/suppfiles/skins/phpZ/logo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/doc-base/master/htmlhelp/suppfiles/skins/phpZ/logo.gif -------------------------------------------------------------------------------- /htmlhelp/suppfiles/skins/phpZ/skin.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/doc-base/master/htmlhelp/suppfiles/skins/phpZ/skin.js -------------------------------------------------------------------------------- /htmlhelp/suppfiles/skins/phpZ/style.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/doc-base/master/htmlhelp/suppfiles/skins/phpZ/style.css -------------------------------------------------------------------------------- /htmlhelp/suppfiles/html/_masterheader.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/doc-base/master/htmlhelp/suppfiles/html/_masterheader.jpg -------------------------------------------------------------------------------- /htmlhelp/suppfiles/quickref/php_manual.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/doc-base/master/htmlhelp/suppfiles/quickref/php_manual.ico -------------------------------------------------------------------------------- /htmlhelp/suppfiles/skins/phpZ/background.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/doc-base/master/htmlhelp/suppfiles/skins/phpZ/background.gif -------------------------------------------------------------------------------- /htmlhelp/suppfiles/skins/phpZ/icn_goTOC.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/doc-base/master/htmlhelp/suppfiles/skins/phpZ/icn_goTOC.gif -------------------------------------------------------------------------------- /htmlhelp/suppfiles/skins/phpZ/icn_next.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/doc-base/master/htmlhelp/suppfiles/skins/phpZ/icn_next.gif -------------------------------------------------------------------------------- /htmlhelp/suppfiles/skins/phpZ/icn_prev.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/doc-base/master/htmlhelp/suppfiles/skins/phpZ/icn_prev.gif -------------------------------------------------------------------------------- /htmlhelp/suppfiles/skins/phpZ/white_fade.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/doc-base/master/htmlhelp/suppfiles/skins/phpZ/white_fade.gif -------------------------------------------------------------------------------- /htmlhelp/suppfiles/prefs/php_manual_prefs.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/doc-base/master/htmlhelp/suppfiles/prefs/php_manual_prefs.exe -------------------------------------------------------------------------------- /htmlhelp/suppfiles/skins/phpZ/icn_bugOnPage.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/doc-base/master/htmlhelp/suppfiles/skins/phpZ/icn_bugOnPage.gif -------------------------------------------------------------------------------- /htmlhelp/suppfiles/skins/phpZ/header_background.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/doc-base/master/htmlhelp/suppfiles/skins/phpZ/header_background.gif -------------------------------------------------------------------------------- /htmlhelp/suppfiles/skins/phpZ/icn_goToFunctionRef.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/doc-base/master/htmlhelp/suppfiles/skins/phpZ/icn_goToFunctionRef.gif -------------------------------------------------------------------------------- /htmlhelp/suppfiles/skins/phpZ/icn_thisPageOnline.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/doc-base/master/htmlhelp/suppfiles/skins/phpZ/icn_thisPageOnline.gif -------------------------------------------------------------------------------- /htmlhelp/suppfiles/skins/phpZ/tabs_corner_active.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/doc-base/master/htmlhelp/suppfiles/skins/phpZ/tabs_corner_active.gif -------------------------------------------------------------------------------- /htmlhelp/suppfiles/skins/phpZ/tabs_corner_inactive.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/doc-base/master/htmlhelp/suppfiles/skins/phpZ/tabs_corner_inactive.gif -------------------------------------------------------------------------------- /htmlhelp/suppfiles/skins/HeaderNostalgia/phpdoc_menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/doc-base/master/htmlhelp/suppfiles/skins/HeaderNostalgia/phpdoc_menu.png -------------------------------------------------------------------------------- /htmlhelp/suppfiles/skins/HeaderNostalgia/phpdoc_php.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/doc-base/master/htmlhelp/suppfiles/skins/HeaderNostalgia/phpdoc_php.png -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "github-actions" 4 | directory: "/" 5 | schedule: 6 | interval: "monthly" 7 | -------------------------------------------------------------------------------- /htmlhelp/suppfiles/skins/HeaderNostalgia/phpdoc_midback.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/doc-base/master/htmlhelp/suppfiles/skins/HeaderNostalgia/phpdoc_midback.png -------------------------------------------------------------------------------- /htmlhelp/suppfiles/skins/HeaderNostalgia/phpdoc_upback.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/doc-base/master/htmlhelp/suppfiles/skins/HeaderNostalgia/phpdoc_upback.png -------------------------------------------------------------------------------- /htmlhelp/suppfiles/skins/phpZ/header_green_background.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/doc-base/master/htmlhelp/suppfiles/skins/phpZ/header_green_background.gif -------------------------------------------------------------------------------- /htmlhelp/suppfiles/skins/phpZ/tabs_background_inactive.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/doc-base/master/htmlhelp/suppfiles/skins/phpZ/tabs_background_inactive.gif -------------------------------------------------------------------------------- /htmlhelp/suppfiles/skins/phpZ/tab_button_pageNotes_active.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/doc-base/master/htmlhelp/suppfiles/skins/phpZ/tab_button_pageNotes_active.gif -------------------------------------------------------------------------------- /htmlhelp/suppfiles/skins/phpZ/tab_button_pageText_active.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/doc-base/master/htmlhelp/suppfiles/skins/phpZ/tab_button_pageText_active.gif -------------------------------------------------------------------------------- /htmlhelp/suppfiles/skins/HeaderNostalgia/phpdoc_bellowmenu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/doc-base/master/htmlhelp/suppfiles/skins/HeaderNostalgia/phpdoc_bellowmenu.png -------------------------------------------------------------------------------- /htmlhelp/suppfiles/skins/HeaderNostalgia/phpdoc_bottomback.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/doc-base/master/htmlhelp/suppfiles/skins/HeaderNostalgia/phpdoc_bottomback.png -------------------------------------------------------------------------------- /htmlhelp/suppfiles/skins/phpZ/tab_button_pageNotes_inactive.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/doc-base/master/htmlhelp/suppfiles/skins/phpZ/tab_button_pageNotes_inactive.gif -------------------------------------------------------------------------------- /htmlhelp/suppfiles/skins/phpZ/tab_button_pageText_inactive.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/doc-base/master/htmlhelp/suppfiles/skins/phpZ/tab_button_pageText_inactive.gif -------------------------------------------------------------------------------- /chm/manual.chm.xml: -------------------------------------------------------------------------------- 1 | 2 | &CHMEdition; 3 | &chmonly.aboutchm; 4 | &chmonly.usingchm; 5 | &chmonly.search; 6 | &chmonly.integration; 7 | 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Files generated by the configure script 2 | .manual.xml 3 | .revcheck.json 4 | version.xml 5 | sources.xml 6 | # File use to generate entities by configure script 7 | fileModHistory.php 8 | 9 | 10 | # A plece for all temporary or generated files (idempotent build) 11 | temp/ 12 | -------------------------------------------------------------------------------- /htmlhelp/suppfiles/html/_skin_hi.js: -------------------------------------------------------------------------------- 1 | // This is an inline skin file for the "Hi" skin of the PHP Manual. 2 | // This file should be inside the Manual CHM file. 3 | 4 | // Get style sheet file 5 | document.write( 6 | // Get the lo style file 7 | '' 8 | ); 9 | 10 | // Display the page to the user 11 | function displayPage() { defaultDisplayPage(); } -------------------------------------------------------------------------------- /htmlhelp/suppfiles/html/_skin_lo.js: -------------------------------------------------------------------------------- 1 | // This is an inline skin file for the "Lo" skin of the PHP Manual. 2 | // This file should be inside the Manual CHM file. 3 | 4 | // Get style sheet file 5 | document.write( 6 | // Get the lo style file 7 | '' 8 | ); 9 | 10 | // Display the page to the user 11 | function displayPage() { defaultDisplayPage(); } -------------------------------------------------------------------------------- /htmlhelp/make-xchm: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | cd .. 4 | cvs -q up 5 | autoconf 6 | ./configure --with-chm=yes --without-internals 7 | make test 8 | make test_xml 9 | make chm_xsl 10 | 11 | cd htmlhelp 12 | rm -f mirrors.inc all 13 | 14 | wget http://php.net/include/mirrors.inc 15 | wget http://php.net/backend/notes/all.bz2 16 | 17 | bunzip2 all.bz2 18 | ./make_chm.bat 19 | cd release 20 | zip -9 -r php_manual_chm.zip * 21 | -------------------------------------------------------------------------------- /htmlhelp/suppfiles/notes/_style.css: -------------------------------------------------------------------------------- 1 | body { background-color: #FFFFFF; color: #000000; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px} 2 | .unheader { background-color: #CCCCCC; padding-left: 5px; padding-top: 1px; padding-right: 10px; padding-bottom: 1px; margin-bottom: 1px} 3 | .untext { background-color: #DDDDDD; margin-top: 0px; padding-top: 2px; padding-right: 10px; padding-bottom: 2px; padding-left: 5px} 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This repository contains the base source files and tools for converting 2 | PHP's documentation, written in DocBook XML, into various presentation 3 | formats like HTML and RTF. 4 | 5 | Documentation for the tools used for building the PHP documentation and 6 | how to contribute to the documentation and translations can be found in 7 | [the `docs` directory](docs/README.md). 8 | 9 | If you just want to read the documentation for PHP, look at: 10 | https://www.php.net/docs.php 11 | -------------------------------------------------------------------------------- /htmlhelp/suppfiles/notes/_index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PHP Manual - User Notes 6 | 7 | 8 | 9 |

10 | The objective of this file is to store PHP Manual 11 | User Notes on your machine. This file is not intended 12 | to be used for viewing. 13 |

14 |

15 | Please put this file into the directory of your 16 | local php_manual_LANG.chm, and so you will be able to 17 | read user notes viewing that file. 18 |

19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/tools.md: -------------------------------------------------------------------------------- 1 | # Tools 2 | 3 | ## Quality Assurance Tools (QA Tools) 4 | 5 | There are various scripts available to ensure the quality of the documentation 6 | and find issues with it, they are located in the `scripts/qa/` directory. 7 | 8 | There might be some more just in `scripts/` but they need to be checked if they 9 | are still relevant and/or given some love. 10 | 11 | ## Translation Tools 12 | 13 | There are also various scripts to ensure the quality and synchrony of 14 | documentation translations, located in the `scripts/translation/` directory. 15 | -------------------------------------------------------------------------------- /scripts/include/lib-misc.inc.php: -------------------------------------------------------------------------------- 1 | isFile()) { 12 | continue; 13 | } 14 | 15 | $filepath = $file->getPathname(); 16 | 17 | if (!in_array(pathinfo($filepath, PATHINFO_EXTENSION), $extensions)) { 18 | continue; 19 | } 20 | 21 | $files[] = $filepath; 22 | } 23 | return $files; 24 | } 25 | 26 | -------------------------------------------------------------------------------- /funcindex.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | &IndexListing; 5 |
6 | &FunctionListing; 7 | &FunctionListingDescription; 8 | 9 |
10 |
11 | &ExampleListing; 12 | &ExampleListingDescription; 13 | 14 |
15 |
16 | -------------------------------------------------------------------------------- /htmlhelp/suppfiles/prefs/php_manual_prefs.js: -------------------------------------------------------------------------------- 1 | prefs_online = true; 2 | prefs_mirror = "http://www.php.net/"; 3 | prefs_context_override = true; 4 | prefs_context_names = Array( 5 | "Manual TOC", 6 | "Function Reference", 7 | "Functions Index", 8 | "_Separator_", 9 | "Copy selection to clipboard", 10 | "Google Search Selection", 11 | "AlltheWeb SearchBox" 12 | ); 13 | prefs_context_values = Array( 14 | "index.html", 15 | "funcref.html", 16 | "indexes.html", 17 | "_Separator_", 18 | "copySelection()", 19 | "searchSelGoogle()", 20 | "_ATWSearch_" 21 | ); 22 | prefs_skin = "Low"; 23 | prefHandler(); 24 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | # The following volunteers have self-identified as subject matter experts 2 | # or interested parties over a particular area of this repository. 3 | # While requesting a review from someone does not obligate that person to 4 | # review a pull request, these reviewers might have valuable knowledge of 5 | # the problem area and could aid in deciding whether a pull request is ready 6 | # for merging. 7 | # 8 | # For more information, see the GitHub CODEOWNERS documentation: 9 | # https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners 10 | 11 | /scripts/translation/ @alfsb 12 | -------------------------------------------------------------------------------- /scripts/docgen/versions.tpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {VERSIONS} 5 | 6 | 26 | -------------------------------------------------------------------------------- /htmlhelp/suppfiles/html/_function.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Function Redirect 6 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/public-builds.md: -------------------------------------------------------------------------------- 1 | # How the manual is built for the website 2 | 3 | The manual and all of its translations is automatically rebuilt and 4 | made available at PHP.net through a regular process handled by the 5 | systems team. 6 | 7 | Currently, this happens every few hours. 8 | 9 | If there appear to be problems with the regular building of the manual or 10 | any translation, contact the [PHP Systems team](mailto:systems@php.net) 11 | for help. (The process is automated and monitored, so problems are 12 | generally dealt with promptly.) 13 | 14 | ## CHM builds 15 | 16 | The CHM versions of the manual are currently built by [Yoshinari 17 | Takaoka](https://github.com/mumumu) on an irregular schedule, and are 18 | automatically made available for distribution when they are rebuilt. 19 | -------------------------------------------------------------------------------- /scripts/docgen/constants.tpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | &reftitle.constants; 4 | {CONSTANTS} 5 | 6 | 26 | -------------------------------------------------------------------------------- /docs/toc.md: -------------------------------------------------------------------------------- 1 | ## Table of Contents 2 | - [Introduction](README.md) 3 | - [Overview of the build system](overview.md) 4 | - [Contributing to the documentation](contributing.md) 5 | - [Setting up a local build environment](local-setup.md) 6 | - [Editing the PHP Manual](editing.md) 7 | - [Documentation structure](structure.md) 8 | - [Style guidelines](style.md) 9 | - [Coding standard for examples](cs-for-examples.md) 10 | - [Translating documentation](translating.md) 11 | - [Joining the team](joining.md) 12 | 13 | ## Appendices 14 | - [FAQ](faq.md) 15 | - [Tools](tools.md) 16 | - [Frequently used tags and entities](tags-and-entities.md) 17 | - [User Note Editing Guidelines](user-notes.md) 18 | - [Setting up a local web development environment](local-web-setup.md) 19 | - [How the released versions are built](public-builds.md) 20 | -------------------------------------------------------------------------------- /scripts/docgen/configure.tpl: -------------------------------------------------------------------------------- 1 | 2 |
3 | &reftitle.install; 4 | 5 | {EXT_INSTALL_MAIN} 6 | {EXT_INSTALL_WIN} 7 |
8 | 28 | -------------------------------------------------------------------------------- /scripts/docgen/reference.tpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | {EXT_NAME} &Functions; 4 | 5 | &reference.{EXT_NAME_ID}.entities.functions; 6 | 7 | 8 | 28 | -------------------------------------------------------------------------------- /docbook/docbook-v5.2-os/dbits.nvdl: -------------------------------------------------------------------------------- 1 | 2 | 10 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /docbook/docbook-v5.2-os/docbook.nvdl: -------------------------------------------------------------------------------- 1 | 2 | 10 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /docbook/docbook-v5.2-os/assembly.nvdl: -------------------------------------------------------------------------------- 1 | 2 | 10 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /docs/local-web-setup.md: -------------------------------------------------------------------------------- 1 | # Setting up a local web development enviroment 2 | 3 | ## Clone the php.net sources 4 | ``` 5 | $ git clone https://github.com/php/web-php.git 6 | ``` 7 | 8 | ## Symlink (or move) the generated PHP documentation to your local php.net sources 9 | ``` 10 | $ cd web-php/manual 11 | $ rm -rf en 12 | $ ln -s ../../output/php-web en 13 | ``` 14 | 15 | Symlinking can also be done on Windows. Just make sure you run `cmd` as an *Administrator*. 16 | 17 | ``` 18 | $ cd \your\path\to\web-php\manual\ 19 | $ rmdir /S en 20 | $ mklink /D en \your\path\to\output\web-php 21 | ``` 22 | 23 | ## Run a webserver 24 | We are going to use PHP's built-in web server. Please open another terminal instance for this task. 25 | 26 | ``` 27 | $ cd phpdoc/web-php 28 | $ php -S localhost:8080 .router.php 29 | ``` 30 | 31 | ## View the new site 32 | Open [http://localhost:8080/manual/en/](http://localhost:8080/manual/en/) in your browser. 33 | -------------------------------------------------------------------------------- /scripts/helpers/phpdoc-completion.sh: -------------------------------------------------------------------------------- 1 | # ex: ts=4 sw=4 et filetype=sh 2 | 3 | _phpdoc() 4 | { 5 | local cur opts 6 | COMPREPLY=() 7 | cur="${COMP_WORDS[COMP_CWORD]}" 8 | opts=" 9 | --help 10 | --version 11 | --quiet 12 | --srcdir= 13 | --basedir= 14 | --rootdir= 15 | --enable-force-dom-save 16 | --enable-chm 17 | --enable-howto 18 | --with-lang= 19 | --disable-segfault-error 20 | --disable-segfault-speed 21 | --disable-version-files 22 | --disable-libxml-check 23 | --with-php= 24 | --with-partial= 25 | --generate= 26 | --output= 27 | --disable-broken-file-listing 28 | --redirect-stderr-to-stdout" 29 | 30 | if [[ ${cur} == -* ]] ; then 31 | COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) 32 | return 0 33 | fi 34 | } 35 | 36 | complete -F _phpdoc phpdoc -------------------------------------------------------------------------------- /skeletons/versions.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 32 | -------------------------------------------------------------------------------- /htmlhelp/suppfiles/skins/GreenLinks/skin.js: -------------------------------------------------------------------------------- 1 | // This is a sample skin for the CHM edition of the PHP Manual. 2 | // This skin should be in a "skins/greenlinks" subdir of the folder 3 | // containing the CHM (as assumed by the CSS loader in this file) 4 | 5 | // This skin is only here to demonstrate how to modify 6 | // CSS properties for your working pleasure. The style sheet 7 | // presented is the same as the 'low' sheet, except that 8 | // all the link are green, just to prove that you see a 9 | // different style sheet in action. 10 | 11 | // Feel free to play with the styles, the commets should help you 12 | // to get started. Please submit any nice skins to the php-doc-chm 13 | // mailing list . Thanks. 14 | 15 | // Get style sheet file 16 | document.write( 17 | // Get our style file 18 | '' 19 | ); 20 | 21 | // Display the page to the user 22 | function displayPage() { defaultDisplayPage(); } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Documentation content licensing: 2 | 3 | Copyright © 1997 - 2017 by the PHP Documentation Group. This material 4 | may be distributed only subject to the terms and conditions set forth 5 | in the Creative Commons Attribution 3.0 License or later. A copy of 6 | the Creative Commons Attribution 3.0 license is distributed with this 7 | manual. The latest version is presently available at » 8 | http://creativecommons.org/licenses/by/3.0/. 9 | 10 | If you are interested in redistribution or republishing of this 11 | document in whole or in part, either modified or unmodified, and you 12 | have questions, please contact the Copyright holders at » 13 | doc-license@lists.php.net. Note that this address is mapped to a 14 | publicly archived mailing list. 15 | 16 | Documentation tools licensing: 17 | 18 | Most of the custom scripts used to build the documentation are 19 | under the PHP License. Please check the license headers in the 20 | files for more details. 21 | 22 | -------------------------------------------------------------------------------- /scripts/docgen/examples.tpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | &reftitle.examples; 4 | 5 | {EXT_NAME} Example 6 | 7 | 13 | ]]> 14 | 15 | &example.outputs.similar; 16 | 17 | 20 | 21 | 22 | 23 | 43 | -------------------------------------------------------------------------------- /skeletons/book.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Long title of extension 4 | Extname 5 | 6 | 7 | 8 | &reftitle.intro; 9 | 10 | Extension introduction. 11 | 12 | 13 | 14 | 15 | &reference.extname.setup; 16 | &reference.extname.constants; 17 | &reference.extname.reference; 18 | 19 | 20 | 40 | -------------------------------------------------------------------------------- /scripts/docgen/book.tpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | {EXT_NAME} 4 | {EXT_NAME} 5 | 6 | 7 | &reftitle.intro; 8 | 9 | Extension introduction. 10 | 11 | 12 | 13 | &reference.{EXT_NAME_ID}.setup; 14 | &reference.{EXT_NAME_ID}.constants; 15 | &reference.{EXT_NAME_ID}.examples; 16 | &reference.{EXT_NAME_ID}.reference; 17 | 18 | 19 | 39 | -------------------------------------------------------------------------------- /htmlhelp/mirrors_ini.php: -------------------------------------------------------------------------------- 1 | $mirrorinfo) { 34 | if ($mirrorinfo[7] == MIRROR_OK) { 35 | fwrite($fp, "mirror = \"$mirror\"\n"); 36 | } 37 | } 38 | 39 | fclose($fp); 40 | 41 | ?> -------------------------------------------------------------------------------- /skeletons/reference.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Extname &Functions; 4 | Extname 5 | 6 | 16 | 17 | &reference.extname.entities.functions; 18 | 19 | 20 | 40 | -------------------------------------------------------------------------------- /skeletons/configure.xml: -------------------------------------------------------------------------------- 1 | 2 |
3 | &reftitle.install; 4 | 5 | 6 | 7 | 8 | 9 | To enable extname support, configure PHP with 10 | 11 | 12 | 13 | Windows users ... 14 | 15 |
16 | 36 | -------------------------------------------------------------------------------- /scripts/docgen/ini.tpl: -------------------------------------------------------------------------------- 1 | 2 |
3 | &reftitle.runtime; 4 | &extension.runtime; 5 | 6 | 7 | {EXT_NAME} &ConfigureOptions; 8 | 9 | 10 | 11 | &Name; 12 | &Default; 13 | &Changeable; 14 | &Changelog; 15 | 16 | 17 | {INI_ENTRIES} 18 | 19 |
20 | 21 | 22 | &ini.descriptions.title; 23 | {INI_ENTRIES_DESCRIPTION} 24 | 25 |
26 | 46 | -------------------------------------------------------------------------------- /scripts/docgen/setup.tpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | &reftitle.setup; 4 | 5 |
6 | &reftitle.required; 7 | 8 | 9 | 10 |
11 | 12 |
13 | &reftitle.install; 14 | &no.install; 15 |
16 | 17 |
18 | &reftitle.runtime; 19 | &no.config; 20 |
21 | 22 |
23 | &reftitle.resources; 24 | 25 | 26 | 27 |
28 | 29 |
30 | 50 | -------------------------------------------------------------------------------- /scripts/translation/libqa/SyncFileItem.php: -------------------------------------------------------------------------------- 1 | | 14 | +----------------------------------------------------------------------+ 15 | 16 | # Description 17 | 18 | Holds file related data for synq XML tools. */ 19 | 20 | require_once __DIR__ . '/all.php'; 21 | 22 | class SyncFileItem 23 | { 24 | public string $sourceDir; 25 | public string $targetDir; 26 | public string $file; 27 | } 28 | -------------------------------------------------------------------------------- /docs/tags-and-entities.md: -------------------------------------------------------------------------------- 1 | # Some popular tags and entities 2 | 3 | filenames 4 | constants 5 | variables 6 | a function's parameter/argument 7 | functions, this links to function pages or bolds if 8 | already on the function's page. it also adds (). 9 | 10 | teletype/mono-space font 11 | italics 12 | see HOWTO, includes many other tags. 13 | internal manual links 14 | variables 15 | 16 | external links via global.ent 17 | mmm cookies 18 | 19 | types, this links to the given types manual 20 | page: object -> php.net/types.object 21 | 22 | &return.success; see: language-snippets.ent 23 | &true; TRUE 24 | &false; FALSE 25 | &php.ini; php.ini 26 | 27 | Be sure to check out `entities/global.ent` (in the `doc-base` repo) and 28 | `language-snippets.ent` (located within each language's repo) for more 29 | information for entities and URLs. 30 | -------------------------------------------------------------------------------- /scripts/translation/libqa/all.php: -------------------------------------------------------------------------------- 1 | | 14 | +----------------------------------------------------------------------+ 15 | */ 16 | 17 | ini_set( 'display_errors' , 1 ); 18 | ini_set( 'display_startup_errors' , 1 ); 19 | error_reporting( E_ALL ); 20 | 21 | require_once __DIR__ . '/ArgvParser.php'; 22 | require_once __DIR__ . '/OutputBuffer.php'; 23 | require_once __DIR__ . '/OutputIgnore.php'; 24 | require_once __DIR__ . '/SyncFileList.php'; 25 | require_once __DIR__ . '/SyncFileItem.php'; 26 | require_once __DIR__ . '/XmlFrag.php'; 27 | -------------------------------------------------------------------------------- /skeletons/constants.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | &reftitle.constants; 4 | &extension.constants; 5 | 6 | 7 | 8 | 9 | 10 | 11 | CONSTANT_NAME 12 | (itstype) 13 | 14 | 15 | 16 | The constant description. 17 | 18 | 19 | 20 | 21 | 22 | 23 | CONSTANT2_NAME 24 | (itstype) 25 | 26 | 27 | 28 | The description. 29 | 30 | 31 | 32 | 33 | 34 | 35 | 55 | -------------------------------------------------------------------------------- /skeletons/examples.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | &reftitle.examples; 4 | 5 | 6 | 7 |
8 | Basic usage for extname 9 | 10 | A bunch of text 11 | 12 | 13 | A title 14 | 15 | More optional text 16 | 17 | 18 | 22 | ]]> 23 | 24 | &example.outputs.similar; 25 | 26 | 29 | 30 | 31 |
32 | 33 |
34 | 54 | -------------------------------------------------------------------------------- /htmlhelp/split_notes.php: -------------------------------------------------------------------------------- 1 | Previous user note split detected, skipping\n"; 14 | } 15 | 16 | // We have no splitted notes files, do it now 17 | else { 18 | 19 | // Open all notes source file for reading 20 | $fp = @fopen("all", "r"); 21 | if (!$fp) { die("ERROR: No all notes file present"); } 22 | 23 | // Read through the file, and write individual files 24 | while (!feof($fp)) { 25 | $line = chop(fgets($fp,8096)); 26 | if ($line == "") continue; 27 | 28 | // Get data from one line 29 | list($id,$sect,$rate,$ts,$user,$note) = explode("|",$line); 30 | $hash = substr(md5($sect),0,16); 31 | 32 | // Create dir if nonexistent 33 | if (!@is_dir("$NOTES_SRC/" . $hash[0])) { 34 | mkdir("$NOTES_SRC/" . $hash[0], 0700); 35 | } 36 | 37 | // Append line to appropriate file 38 | $nf = fopen("$NOTES_SRC/" . $hash[0] . "/$hash", "a"); 39 | fwrite($nf, $line . "\n"); 40 | fclose($nf); 41 | } 42 | 43 | // Close all notes file 44 | fclose($fp); 45 | 46 | } 47 | 48 | ?> -------------------------------------------------------------------------------- /htmlhelp/suppfiles/quickref/php_quickref.hta: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 17 | 27 | 38 | PHP Manual Quickref 39 | 40 | 41 |
42 | Function:
43 | 44 |
45 | 46 | 47 | -------------------------------------------------------------------------------- /scripts/docgen/function.tpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {FUNCTION_NAME} 5 | Description 6 | 7 | 8 | 9 | &reftitle.description; 10 | 11 | {RETURN_TYPE}{FUNCTION_NAME} 12 | {FUNCTION_PARAMETERS} 13 | 14 | 15 | 16 | 17 | 18 | &warn.undocumented.func; 19 | 20 | 21 | 22 | 23 | &reftitle.parameters; 24 | {PARAMETERS_DESCRIPTION} 25 | 26 | 27 | 28 | &reftitle.returnvalues; 29 | 30 | 31 | 32 | 33 | {DEFAULT_EXAMPLE} 34 | {DEFAULT_SEEALSO} 35 | 36 | 56 | -------------------------------------------------------------------------------- /scripts/docgen/method.tpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {FULL_METHOD_NAME} 5 | Description 6 | 7 | 8 | 9 | &reftitle.description; 10 | 11 | {MODIFIERS}{RETURN_TYPE}{FULL_METHOD_NAME} 12 | {METHOD_PARAMETERS} 13 | 14 | 15 | 16 | 17 | 18 | &warn.undocumented.func; 19 | 20 | 21 | 22 | 23 | &reftitle.parameters; 24 | {PARAMETERS_DESCRIPTION} 25 | 26 | 27 | 28 | &reftitle.returnvalues; 29 | 30 | 31 | 32 | 33 | {DEFAULT_EXAMPLE} 34 | {DEFAULT_SEEALSO} 35 | 36 | 56 | -------------------------------------------------------------------------------- /htmlhelp/TODO.txt: -------------------------------------------------------------------------------- 1 | ! Please contact goba@php.net before modifying 2 | ! the code in the "htmlhelp" folder in CVS. 3 | 4 | Important: 5 | 6 | - Add _function.html to the resulting CHM, 7 | which can redirect to a function page in 8 | the CHM. IDEs without direct PHP manual 9 | support can use this to integrate the CHM. 10 | 11 | - Make the build system support other languages 12 | then English. All the strings used need to be 13 | customizable. This also includes the porting 14 | of the charset conversion added lately to the 15 | "old chm" build system. 16 | 17 | - Make the build system run more automatically. 18 | 19 | - Make the build system run on Unix (except the 20 | hh compiler). 21 | 22 | Additional: 23 | 24 | - Do not clean up the notesin and notesout 25 | directories if recently generated files 26 | are there (the "all" file is older then 27 | those files generated there). 28 | 29 | - Also do not clean up the "htmlout" directory 30 | if the files there are newer then the ones 31 | in the "html" directory. 32 | 33 | - Implement some detection for the $HTML_SRC 34 | and $HTML_TARGET directories, and don't do 35 | cleanups, and some copying, if they are the 36 | same. 37 | 38 | - Experiment with Brendan Ferguson's JS syntax 39 | highlighter and test it's usage in user note 40 | coloring. This would make the resulting CHMs 41 | much smaller, but needs JS magic (may be slow). 42 | 43 | - Document the skin framework, how it works, so 44 | others will be able to create their own skins. 45 | -------------------------------------------------------------------------------- /skeletons/setup.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | &reftitle.setup; 4 | 5 | 6 | 7 |
8 | &reftitle.required; 9 | &no.requirement; 10 |
11 | 12 | 13 | 14 |
15 | &reftitle.install; 16 | &no.install; 17 |
18 | 19 | 20 | 21 | 22 |
23 | &reftitle.runtime; 24 | &no.config; 25 |
26 | 27 | 28 | 29 | 30 |
31 | &reftitle.resources; 32 | &no.resource; 33 |
34 | 35 | 36 |
37 | 57 | -------------------------------------------------------------------------------- /scripts/translation/configure.php: -------------------------------------------------------------------------------- 1 | | 15 | * +----------------------------------------------------------------------+ 16 | * | Description: Generate cached data for revcheck and QA tools. | 17 | * +----------------------------------------------------------------------+ 18 | */ 19 | 20 | require_once __DIR__ . '/lib/all.php'; 21 | 22 | if ( count( $argv ) < 2 || in_array( '--help' , $argv ) || in_array( '-h' , $argv ) ) 23 | { 24 | fwrite( STDERR , "Usage: {$argv[0]} [lang_dir]\n\n" ); 25 | fwrite( STDERR , "See https://github.com/php/doc-base/tree/master/scripts/translation#readme for more info.\n" ); 26 | return; 27 | } 28 | 29 | new RevcheckRun( 'en' , $argv[1] , true ); 30 | -------------------------------------------------------------------------------- /.github/workflows/integrate.yaml: -------------------------------------------------------------------------------- 1 | # https://docs.github.com/en/actions 2 | 3 | name: "Integrate" 4 | 5 | on: 6 | pull_request: null 7 | push: 8 | branches: 9 | - "master" 10 | 11 | jobs: 12 | build: 13 | name: "Build" 14 | 15 | runs-on: "ubuntu-latest" 16 | 17 | continue-on-error: true 18 | 19 | strategy: 20 | matrix: 21 | language: 22 | - "de" 23 | - "en" 24 | - "es" 25 | - "fr" 26 | - "it" 27 | - "ja" 28 | - "pl" 29 | - "pt_br" 30 | # - "ro" 31 | - "ru" 32 | - "tr" 33 | - "uk" 34 | - "zh" 35 | 36 | steps: 37 | - name: "Checkout" 38 | uses: "actions/checkout@v6" 39 | with: 40 | path: "doc-base" 41 | 42 | - name: "Checkout php/doc-${{ matrix.language }}" 43 | uses: "actions/checkout@v6" 44 | with: 45 | path: "${{ matrix.language }}" 46 | repository: "php/doc-${{ matrix.language }}" 47 | 48 | - name: "Checkout php/doc-en as fallback" 49 | if: "matrix.language != 'en'" 50 | uses: "actions/checkout@v6" 51 | with: 52 | path: "en" 53 | repository: "php/doc-en" 54 | 55 | - name: "Run QA scripts for EN docs" 56 | if: "matrix.language == 'en'" 57 | run: | 58 | php doc-base/scripts/qa/extensions.xml.php --check 59 | php doc-base/scripts/qa/section-order.php 60 | 61 | - name: "Build documentation for ${{ matrix.language }}" 62 | run: "php doc-base/configure.php --disable-libxml-check --enable-xml-details --redirect-stderr-to-stdout --with-lang=${{ matrix.language }}" 63 | -------------------------------------------------------------------------------- /chm/make_chm_style.css: -------------------------------------------------------------------------------- 1 | BODY { 2 | FONT-FAMILY: Verdana,arial,helvetica,sans-serif; FONT-SIZE: 10pt 3 | } 4 | TD { 5 | FONT-FAMILY: Verdana,arial,helvetica,sans-serif; FONT-SIZE: 10pt 6 | } 7 | TH { 8 | FONT-FAMILY: Verdana,arial,helvetica,sans-serif; FONT-SIZE: 10pt 9 | } 10 | P { 11 | MARGIN-BOTTOM: 2pt; MARGIN-TOP: 10pt 12 | } 13 | EM { 14 | FONT-STYLE: italic; FONT-WEIGHT: bold 15 | } 16 | UL { 17 | MARGIN-TOP: 10pt 18 | } 19 | OL { 20 | MARGIN-TOP: 10pt 21 | } 22 | PRE { 23 | FONT-FAMILY: "andale mono", "monotype.com", "courier new", monospace; FONT-SIZE: 10pt 24 | } 25 | A.nav { 26 | COLOR: #000066; TEXT-DECORATION: none; FONT-WEIGHT: bold 27 | } 28 | A.nav:hover { 29 | COLOR: #000066; TEXT-DECORATION: underline; FONT-WEIGHT: bold 30 | } 31 | H1 { 32 | COLOR: #000066; FONT-FAMILY: tahoma,arial,helvetica,sans-serif; FONT-SIZE: 18pt; FONT-WEIGHT: bold; MARGIN-BOTTOM: 5pt 33 | } 34 | H2 { 35 | COLOR: #000066; FONT-FAMILY: tahoma,arial,helvetica,sans-serif; FONT-SIZE: 14pt; FONT-WEIGHT: bold; MARGIN-BOTTOM: 5pt 36 | } 37 | H3 { 38 | COLOR: #000066; FONT-FAMILY: tahoma,arial,helvetica,sans-serif; FONT-SIZE: 12pt; FONT-WEIGHT: bold; MARGIN-BOTTOM: 5pt 39 | } 40 | SMALL { 41 | FONT-FAMILY: arial,helvetica,sans-serif; FONT-SIZE: 8.5pt 42 | } 43 | .tableTitle { 44 | FONT-FAMILY: arial,helvetica,sans-serif; FONT-SIZE: 12pt; FONT-WEIGHT: bold 45 | } 46 | .tableExtras { 47 | COLOR: #ffffff; FONT-FAMILY: arial,helvetica,sans-serif; FONT-SIZE: 8.5pt 48 | } 49 | 50 | TABLE.warning, TABLE.caution { 51 | border-color : #B22222; 52 | background-color : #EEE8AA; 53 | border-width : 2; 54 | font : bold normal Arial, Helvetica, sans-serif; 55 | margin : 0; 56 | border-spacing : 0px; 57 | } 58 | -------------------------------------------------------------------------------- /chm/make_chm.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | rem !! Please read the make_chm.README file for information 4 | rem !! about how to build a "php_manual_lang.chm" file. 5 | 6 | rem Path of the PHP CLI executable 7 | set PHP_PATH=php 8 | 9 | rem Path of the Help Compiler command line tool 10 | set PHP_HELP_COMPILER=C:\progra~1\htmlhe~1\hhc.exe 11 | 12 | rem The source directory with the original DSSSL made HTML 13 | set PHP_HELP_COMPILE_DIR=html 14 | 15 | rem The directory, where the fancy files need to be copied 16 | set PHP_HELP_COMPILE_FANCYDIR=chm\fancy 17 | 18 | rem ========================================================== 19 | rem !!!!! DO NOT MODIFY ANYTHING BELOW THIS LINE !!!!! 20 | rem ========================================================== 21 | 22 | 23 | echo. 24 | 25 | set PHP_HELP_COMPILE_LANG=%1 26 | if "%1" == "" set PHP_HELP_COMPILE_LANG=en 27 | 28 | echo Language choosen: %PHP_HELP_COMPILE_LANG% 29 | 30 | REM %1 = en, %2 = -D %3 = . %4 = normal 31 | if a%4a == anormala goto skipfancy 32 | 33 | echo Now generating the fancy manual in %PHP_HELP_COMPILE_FANCYDIR% dir... 34 | IF NOT EXIST %PHP_HELP_COMPILE_FANCYDIR%\NUL md %PHP_HELP_COMPILE_FANCYDIR% 35 | %PHP_PATH% chm\make_chm_fancy.php 36 | 37 | goto normal 38 | 39 | :skipfancy 40 | set PHP_HELP_COMPILE_FANCYDIR= 41 | echo Skipping fancy manual generation... 42 | 43 | :normal 44 | 45 | echo Now running the toc and project file generator script... 46 | %PHP_PATH% chm\make_chm.php 47 | 48 | echo Compiling the actual helpfile (php_manual_%PHP_HELP_COMPILE_LANG%.chm)... 49 | %PHP_HELP_COMPILER% chm\php_manual_%PHP_HELP_COMPILE_LANG%.hhp 50 | 51 | echo. 52 | echo Cleaning up the directory 53 | del chm\php_manual_%PHP_HELP_COMPILE_LANG%.hh? 54 | 55 | echo Done! 56 | echo. 57 | -------------------------------------------------------------------------------- /scripts/docgen/constructor.tpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {FULL_METHOD_NAME} 5 | Description 6 | 7 | 8 | 9 | &reftitle.description; 10 | 11 | {MODIFIERS}{RETURN_TYPE}{FULL_METHOD_NAME} 12 | {METHOD_PARAMETERS} 13 | 14 | 15 | 16 | 17 | 18 | &warn.undocumented.func; 19 | 20 | 21 | 22 | 23 | &reftitle.parameters; 24 | {PARAMETERS_DESCRIPTION} 25 | 26 | 27 | 37 | 38 | {DEFAULT_EXAMPLE} 39 | {DEFAULT_SEEALSO} 40 | 41 | 61 | -------------------------------------------------------------------------------- /scripts/docgen/mapping.tpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {FULL_METHOD_NAME} 5 | {FUNCTION_NAME} 6 | Description 7 | 8 | 9 | 10 | &reftitle.description; 11 | &style.oop; (method): 12 | 13 | {MODIFIERS}{RETURN_TYPE}{FULL_METHOD_NAME} 14 | {METHOD_PARAMETERS} 15 | 16 | &style.procedural;: 17 | 18 | ReturnType{FUNCTION_NAME} 19 | {FUNCTION_PARAMETERS} 20 | 21 | 22 | 23 | 24 | 25 | &warn.undocumented.func; 26 | 27 | 28 | 29 | 30 | &reftitle.parameters; 31 | {PARAMETERS_DESCRIPTION} 32 | 33 | 34 | 35 | &reftitle.returnvalues; 36 | 37 | 38 | 39 | 40 | {DEFAULT_EXAMPLE} 41 | {DEFAULT_SEEALSO} 42 | 43 | 63 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # PHP Manual Contribution Guide 2 | 3 | ## Introduction 4 | 5 | PHP is well-known for having excellent documentation. That documentation 6 | is created by volunteers who collectively make changes every day, and 7 | actively translated into many languages. This guide is designed for 8 | people who work on the official PHP documentation. 9 | 10 | The manual is built from the documentation using a tool called 11 | [PhD](https://doc.php.net/phd.php). The [local setup](local-setup.md) 12 | chapter explains how to set up a local development environment. 13 | 14 | The manual is written to the [DocBook 5.2](https://tdg.docbook.org/tdg/5.2/) 15 | XML schema, with one change to allow the `` tag to support 16 | more than one ``, ``, or `` as the 17 | [DocBook 5.1](https://tdg.docbook.org/tdg/5.1/classsynopsis) schema does. 18 | 19 | ## Glossary 20 | 21 | This guide uses some terminology that you have to know. Don't worry, it's easy: 22 | 23 | - **author** - person who contributes to the original English manual 24 | - **translator** - person who translates the English manual into another 25 | language 26 | - **{LANG}** - replace it with your two-letter country code, (e.g. when 27 | referring to a mailinglist, `doc-{LANG}@lists.php.net`). Note: 28 | Brazilian Portuguese differs from the rest and it's called *pt_br* 29 | for the Git repo and *pt-br* for the mailing list suffix. 30 | 31 | ## Feedback 32 | 33 | You can report problems or make contributions to this guide by using the 34 | "Edit this page" or "Report a problem" links in the sidebar of each page 35 | of [the online version of this documentation](https://doc.php.net/guide/), 36 | or through [the GitHub repository](https://www.github.com/php/doc-base/). 37 | -------------------------------------------------------------------------------- /scripts/translation/qaxml-revtag.php: -------------------------------------------------------------------------------- 1 | | 14 | +----------------------------------------------------------------------+ 15 | 16 | # Description 17 | 18 | Inspect revision tag usage inside XML files. */ 19 | 20 | require_once __DIR__ . '/libqa/all.php'; 21 | require_once __DIR__ . '/lib/RevtagParser.php'; 22 | 23 | $argv = new ArgvParser( $argv ); 24 | $ignore = new OutputIgnore( $argv ); // may exit. 25 | $ignore->appendIgnoreCommands = false; 26 | $argv->complete(); 27 | 28 | $list = SyncFileList::load(); 29 | 30 | foreach ( $list as $file ) 31 | { 32 | $target = $file->targetDir . '/' . $file->file; 33 | $revtag = RevtagParser::parseFile( $target ); 34 | 35 | if ( count( $revtag->errors ) == 0 ) 36 | continue; 37 | 38 | print "# qaxml.r: $target\n"; 39 | foreach( $revtag->errors as $error ) 40 | print " $error\n"; 41 | print "\n"; 42 | } 43 | -------------------------------------------------------------------------------- /scripts/docgen/class.tpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | The {CLASS_NAME} {CLASS_TYPE} 4 | {CLASS_NAME} 5 | 6 | 7 | 8 | 9 |
10 | &reftitle.intro; 11 | 12 | 13 | 14 |
15 | 16 | 17 |
18 | &reftitle.classsynopsis; 19 | 20 | 21 | 22 | 23 | {CLASS_NAME} 24 | 25 | 26 | 27 | 28 | {CLASS_NAME} 29 | 30 | {EXTENDS} 31 | {IMPLEMENTS} 32 | 33 | 34 | {CONSTANTS_LIST} 35 | {PROPERTIES_LIST} 36 | {METHOD_XINCLUDE} 37 | {INHERITED_XINCLUDE} 38 | 39 | 40 | 41 |
42 | 43 | {PROPERTIES} 44 | {CONSTANTS} 45 | 46 |
47 | 48 | &reference.{EXT_NAME_ID}.entities.{CLASS_NAME_ID}; 49 | 50 |
51 | 71 | -------------------------------------------------------------------------------- /htmlhelp/suppfiles/notes/_notes_script.js: -------------------------------------------------------------------------------- 1 | // RAQ : Tuesday, 15 March 2005 03:20 pm : Allow notes from searches to call the original manual page and get the notes skinned. 2 | // Get the path and name of the CHM file and assign values 3 | function loadWithNotes() { 4 | var a, X, Y, Z; 5 | a = location.href.search(/:/); 6 | Y = location.href.lastIndexOf("::"); 7 | 8 | if (a == 4) { // file: or http: 9 | Y = location.href.lastIndexOf("/"); 10 | chmfile_page = unescape(location.href.substring(Y+1)); 11 | if (location.href.substring(0,4) == "file") 12 | chmfile_path = unescape(location.href.substring(8, Y+1)); 13 | } else { 14 | if (a == 2) 15 | X = 14; // mk:@MSITStore: 16 | if (a == 7) 17 | X = 7; // ms-its: 18 | 19 | chmfile_fullname = unescape(location.href.substring(X, Y)); 20 | Z = chmfile_fullname.lastIndexOf("\\"); 21 | chmfile_path = unescape(chmfile_fullname.substring(0, Z+1)); 22 | chmfile_name = unescape(chmfile_fullname.substring(Z+1)); 23 | chmfile_page = unescape(location.href.substring(Y+3)); 24 | } 25 | 26 | //alert( 27 | // "_notes_script\n\n" + 28 | // "location\n"+ 29 | // "location.hash = '" + location.hash + "'\n" + 30 | // "location.host = '" + location.host + "'\n" + 31 | // "location.hostname = '" + location.hostname + "'\n" + 32 | // "location.href = '" + location.href + "'\n" + 33 | // "location.pathname = '" + location.pathname + "'\n" + 34 | // "location.port = '" + location.port + "'\n" + 35 | // "location.protocol = '" + location.protocol + "'\n" + 36 | // "location.search = '" + location.search + "'\n\n" + 37 | // "chmfile\n"+ 38 | // "chmfile_name = '" + chmfile_name + "'\n" + 39 | // "chmfile_path = '" + chmfile_path + "'\n" + 40 | // "chmfile_page = '" + chmfile_page + "'\n" 41 | // ); 42 | 43 | location = location.protocol + '@MSITStore:' + chmfile_path + 'php_manual_en.chm::/' + chmfile_page + '#userNotes'; 44 | } -------------------------------------------------------------------------------- /scripts/check-underdocumented.php: -------------------------------------------------------------------------------- 1 | getPathname(); 36 | $filename = $file->getBasename(); 37 | 38 | if (strpos($filepath, '.svn')) { 39 | continue; 40 | } 41 | 42 | if (!$file->isFile() || pathinfo($filepath, PATHINFO_EXTENSION) !== 'xml') { 43 | continue; 44 | } 45 | 46 | $fileid = str_replace($phpdoc_path, '', $filepath); 47 | $ext = strtok($fileid, DIRECTORY_SEPARATOR); 48 | 49 | if (file_exists($phpdoc_path . $fileid)) { 50 | $contents = file_get_contents($phpdoc_path . $fileid); 51 | if (false !== strpos($contents, 'warn.undocumented.func')) { 52 | $undocumented[$ext][] = $fileid; 53 | ++$count; 54 | } 55 | continue; 56 | } 57 | } 58 | 59 | echo 'List of underdocumented functions/methods', PHP_EOL; 60 | print_r($undocumented); 61 | echo "Number underdocumented: ", $count, PHP_EOL; 62 | 63 | function usage() { 64 | echo PHP_EOL, 'USAGE:', PHP_EOL; 65 | echo 'php ', $_SERVER['SCRIPT_FILENAME'], ' -p /path/to/phpdoc/en/reference/', PHP_EOL; 66 | exit; 67 | } -------------------------------------------------------------------------------- /docbook/JING_LICENSE: -------------------------------------------------------------------------------- 1 | 2 | 3 | Jing Copying Conditions 4 | 5 | 6 | 7 |

Jing Copying Conditions

8 | 9 |

Copyright (c) 2001-2003 Thai Open Source Software Center Ltd
10 | All rights reserved.

11 | 12 |

Redistribution and use in source and binary forms, with or without 13 | modification, are permitted provided that the following conditions are 14 | met:

15 | 16 |
    17 |
  • Redistributions of source code must retain the above copyright 18 | notice, this list of conditions and the following disclaimer.
  • 19 | 20 |
  • Redistributions in binary form must reproduce the above copyright 21 | notice, this list of conditions and the following disclaimer in 22 | the documentation and/or other materials provided with the 23 | distribution.
  • 24 | 25 |
  • Neither the name of the Thai Open Source Software Center Ltd nor 26 | the names of its contributors may be used to endorse or promote 27 | products derived from this software without specific prior written 28 | permission.
  • 29 |
30 | 31 |

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 34 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR 35 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 36 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 37 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 38 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 39 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 40 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 41 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /htmlhelp/suppfiles/prefs/context.ini: -------------------------------------------------------------------------------- 1 | # ================================================= 2 | # PHP Manual CHM version context menu configuration 3 | # ================================================= 4 | 5 | # Genaral functions 6 | # ----------------- 7 | 8 | [context_item] 9 | display = "Copy selection to clipboard" 10 | implementation = "copySelection()" 11 | 12 | [context_item] 13 | display = "Select all" 14 | implementation = "selectAll()" 15 | 16 | [context_item] 17 | display = "Print page" 18 | implementation = "print()" 19 | 20 | [context_item] 21 | display = "Back" 22 | implementation = "back()" 23 | 24 | [context_item] 25 | display = "Forward" 26 | implementation = "forward()" 27 | 28 | [context_item] 29 | display = "Refresh" 30 | implementation = "refresh()" 31 | 32 | # Page jump options 33 | # ----------------- 34 | 35 | [context_item] 36 | display = "Manual TOC" 37 | implementation = "index.html" 38 | 39 | [context_item] 40 | display = "Function Reference" 41 | implementation = "funcref.html" 42 | 43 | [context_item] 44 | display = "HTML Help Edition" 45 | implementation = "chmonly.html" 46 | 47 | [context_item] 48 | display = "Functions Index" 49 | implementation = "indexes.html" 50 | 51 | [context_item] 52 | display = "PHP-GTK home" 53 | implementation = "http://gtk.php.net/" 54 | 55 | [context_item] 56 | display = "PEAR home" 57 | implementation = "http://pear.php.net/" 58 | 59 | # Search engine quickforms and selections 60 | # --------------------------------------- 61 | 62 | [context_item] 63 | display = "Google SearchBox" 64 | implementation = "_GoogleSearch_" 65 | 66 | [context_item] 67 | display = "Google Search Selection" 68 | implementation = "searchSelGoogle()" 69 | 70 | [context_item] 71 | display = "AlltheWeb SearchBox" 72 | implementation = "_ATWSearch_" 73 | 74 | [context_item] 75 | display = "AlltheWeb Search Selection" 76 | implementation = "searchSelATW()" -------------------------------------------------------------------------------- /scripts/translation/lib/all.php: -------------------------------------------------------------------------------- 1 | | 15 | * +----------------------------------------------------------------------+ 16 | * | Description: Old style, require all file. | 17 | * +----------------------------------------------------------------------+ 18 | */ 19 | 20 | ini_set( 'display_errors' , 1 ); 21 | ini_set( 'display_startup_errors' , 1 ); 22 | error_reporting( E_ALL ); 23 | 24 | require_once __DIR__ . '/backport.php'; 25 | require_once __DIR__ . '/CacheFile.php'; 26 | require_once __DIR__ . '/CacheUtil.php'; 27 | require_once __DIR__ . '/GitLogParser.php'; 28 | require_once __DIR__ . '/GitSlowUtils.php'; 29 | require_once __DIR__ . '/OutputIgnoreArgv.php'; 30 | require_once __DIR__ . '/OutputIgnoreBuffer.php'; 31 | require_once __DIR__ . '/QaFileInfo.php'; 32 | require_once __DIR__ . '/RevcheckData.php'; 33 | require_once __DIR__ . '/RevcheckFileItem.php'; 34 | require_once __DIR__ . '/RevcheckFileList.php'; 35 | require_once __DIR__ . '/RevcheckIgnore.php'; 36 | require_once __DIR__ . '/RevcheckRun.php'; 37 | require_once __DIR__ . '/RevtagParser.php'; 38 | require_once __DIR__ . '/XmlUtil.php'; 39 | -------------------------------------------------------------------------------- /scripts/notes_extract.php: -------------------------------------------------------------------------------- 1 | | 15 | +----------------------------------------------------------------------+ 16 | 17 | $Id$ 18 | */ 19 | 20 | /* 21 | * Usage: 22 | * $ php notes_extract.php source.mbox > notes.txt 23 | */ 24 | 25 | define('NL', "\n"); 26 | 27 | if (!isset($argv[1]) || $argv[1] == '-h' || $argv[1] == '--help') { 28 | echo 'USAGE: ', $argv[0], ' source.mbox > notes.txt', NL; 29 | exit(1); 30 | } 31 | 32 | if (!file_exists($argv[1])) { 33 | echo 'Error: Could not open file.', NL; 34 | exit(2); 35 | } 36 | 37 | define('SOURCE', $argv[1]); 38 | 39 | $pairs = shell_exec( 40 | 'gawk \'BEGIN { RS = "\n\n" } /Date: ([^\n]+).*Subject: \[PHP-NOTES]/ { print $0 }\' '.SOURCE.' | gawk \'/^Date:/ { print $0 } /^Subject:/ { print $0 }\'' 41 | ); 42 | 43 | $pairs = explode(NL, $pairs); 44 | 45 | //echo 'Processing ', count($pairs) / 2, ' notes...', NL; 46 | 47 | $last = count($pairs); 48 | 49 | for ($i = 0; $i < $last; ++$i) { 50 | if (substr($pairs[$i], 0, 5) != 'Date:') { 51 | continue; 52 | } 53 | 54 | if (substr($pairs[$i + 1], 0, 8) != 'Subject:') { 55 | continue; 56 | } 57 | 58 | echo strtotime(substr($pairs[$i], 6)), ' ', substr($pairs[$i + 1], 9), NL; 59 | } 60 | -------------------------------------------------------------------------------- /htmlhelp/README.txt: -------------------------------------------------------------------------------- 1 | **************************************************************** 2 | ** This build system is used to generate the extended CHM ** 3 | ** file available from php.net (only in English). There is ** 4 | ** a different CHM generator system in the 'chm' folder, ** 5 | ** which is used to build the simpler CHM files (in multiple ** 6 | ** languages). ** 7 | ** ** 8 | ** Both of the systems are used in paralell. ** 9 | **************************************************************** 10 | 11 | Build system of the extended CHMs 12 | ================================= 13 | 14 | [See latest "official" output package online at 15 | http://php.net/docs-echm] 16 | 17 | How to build a CHM manual with this system? 18 | 19 | 0. Ensure that you have the latest phpdoc checkout and the 20 | version information in xsl/version.xml is up-to-date, 21 | so you will build the latest function version information 22 | into the CHM. 23 | 24 | 1. run "autoconf" in the phpdoc directory 25 | 26 | 2. run "./configure --with-chm=yes" 27 | 28 | Optionally you may need to specify the 29 | "--with-xsltproc=path" option to explicitly 30 | provide the XSLTProc path. 31 | 32 | 33 | 3. Run "make chm_xsl" 34 | 35 | If xsltproc encounters errors in the XML files, 36 | correct the errors, commit them to phpdoc, and 37 | run "make chm_xsl" again. There is no need to 38 | reconfigure in most cases. 39 | 40 | After this step the HTML files to start are in 41 | phpdoc/htmlhelp/html 42 | 43 | 4. Get the actual mirrors.inc file from 44 | http://ANY_MIRROR.php.net/include/mirrors.inc 45 | and save into the directory where the 46 | make_chm.bat resides (overwrite old one if 47 | one exists). 48 | 49 | 5. Get all the user notes from 50 | http://ANY_MIRROR.php.net/backend/notes/all.bz2, 51 | extract its contents (using bunzip2 all.bz2, for example), 52 | and place the resulting "all" file to the same folder where 53 | the make_chm.bat resides. 54 | 55 | 6. Copy local_vars.php.src to local_vars.php and 56 | adjust settings as needed. 57 | 58 | 7. Now run make_chm.bat 59 | 60 | Well, this is quite manual right now, and there are 61 | some problems need fixing (see the TODO.txt file too). 62 | -------------------------------------------------------------------------------- /scripts/translation/lib/CacheUtil.php: -------------------------------------------------------------------------------- 1 | | 15 | * +----------------------------------------------------------------------+ 16 | * | Description: Common functions do load and save to cache files. | 17 | * +----------------------------------------------------------------------+ 18 | */ 19 | 20 | require_once __DIR__ . '/all.php'; 21 | 22 | class CacheUtil 23 | { 24 | const CACHE_DIR = __DIR__ . '/../.cache'; 25 | 26 | public static function load( string $path , string $file ) 27 | { 28 | $filename = CacheUtil::prepareFilename( $path , $file , true ); 29 | if ( file_exists( $filename ) == false ) 30 | return null; 31 | $data = file_get_contents( $filename ); 32 | return unserialize( $data ); 33 | } 34 | 35 | public static function save( string $path , string $file , $data ) 36 | { 37 | $outFile = CacheUtil::prepareFilename( $path , $file , true ); 38 | $contents = serialize( $data ); 39 | file_put_contents( $outFile , $contents ); 40 | } 41 | 42 | public static function prepareFilename( string $path , string $file , bool $createDirs = false ) 43 | { 44 | $baseDir = CacheUtil::CACHE_DIR; 45 | $outPath = rtrim( $baseDir , '/' ) . '/' . $path; 46 | $outFile = rtrim( $outPath , '/' ) . '/' . $file; 47 | if ( $createDirs && file_exists( $outPath ) == false ) 48 | mkdir( $outPath , 0777 , true ); 49 | return $outFile; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /scripts/translation/qarvt.php: -------------------------------------------------------------------------------- 1 | | 15 | * +----------------------------------------------------------------------+ 16 | * | Description: Check format for revtags and credits on XML comments. | 17 | * +----------------------------------------------------------------------+ 18 | */ 19 | 20 | require_once __DIR__ . '/lib/all.php'; 21 | 22 | $langDir = ""; 23 | 24 | switch ( count( $argv ) ) 25 | { 26 | case 1: 27 | break; 28 | case 2: 29 | $langDir = $argv[1]; 30 | break; 31 | default: 32 | print_usage_exit($argv[0]); 33 | return; 34 | } 35 | 36 | if ( $langDir == "" ) 37 | { 38 | $qalist = QaFileInfo::cacheLoad(); 39 | if ( count( $qalist ) > 0 ) 40 | { 41 | foreach( $qalist as $qa ) 42 | { 43 | $langDir = $qa->targetDir; 44 | break; 45 | } 46 | } 47 | else 48 | print_usage_exit($argv[0]); 49 | } 50 | 51 | $list = new RevcheckFileList( $langDir ); 52 | 53 | foreach( $list->iterator() as $item ) 54 | { 55 | $file = $langDir . '/' . $item->file; 56 | $revt = RevtagParser::parseFile( $file ); 57 | 58 | if ( count( $revt->errors ) == 0 ) 59 | continue; 60 | 61 | print "qarvt: $file\n"; 62 | foreach( $revt->errors as $error ) 63 | print " $error\n"; 64 | print "\n"; 65 | } 66 | 67 | function print_usage_exit($cmd) 68 | { 69 | fwrite( STDERR , " Wrong paramater count. Usage:\n" ); 70 | fwrite( STDERR , " {$cmd} [lang_dir]:\n" ); 71 | exit; 72 | } 73 | -------------------------------------------------------------------------------- /skeletons/ini.xml: -------------------------------------------------------------------------------- 1 | 2 |
3 | &reftitle.runtime; 4 | &extension.runtime; 5 | 6 | 7 | 8 | 9 | Extname &ConfigureOptions; 10 | 11 | 12 | 13 | &Name; 14 | &Default; 15 | &Changeable; 16 | &Changelog; 17 | 18 | 19 | 20 | 21 | theini_option 22 | itsvalue 23 | its INI_* value 24 | version changes information 25 | 26 | 27 | anotherini_option 28 | itsvalue 29 | its INI_* value 30 | 31 | 32 | 33 | 34 |
35 | 36 | 37 | &ini.php.constants; 38 | 39 | 40 | 41 | 42 | &ini.descriptions.title; 43 | 44 | 45 | 46 | theini_option 47 | thetype 48 | 49 | 50 | 51 | Fill in the description of theini-option. 52 | 53 | 54 | 55 | 56 | 57 | 58 | anotherini_option 59 | thetype 60 | 61 | 62 | 63 | Fill in the description of anotherini-option. 64 | 65 | 66 | 67 | 68 | 69 |
70 | 90 | -------------------------------------------------------------------------------- /scripts/qa/check-missing-initializers.php: -------------------------------------------------------------------------------- 1 | tag. 5 | - Pass in a path and it'll check it. The path might include all of phpdoc, or a simple extension 6 | TODO: 7 | - Determine what initializer values should be as some cases aren't clear 8 | */ 9 | 10 | $opts = getopt('p:oh'); 11 | 12 | if (isset($opts['h'])) { 13 | usage(); 14 | } 15 | if (empty($opts['p'])) { 16 | echo "\nERROR:\n - A path is required\n"; 17 | usage(); 18 | } 19 | if (!is_dir($opts['p'])) { 20 | echo "\nERROR:\n - Please pass in a real directory, unlike this mysterious '$opts[p]'\n"; 21 | usage(); 22 | } 23 | 24 | $empty = []; 25 | $count_total = 0; 26 | $count_empty = 0; 27 | 28 | foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($opts['p'])) as $file) { 29 | 30 | $filepath = $file->getPathname(); 31 | $filename = $file->getBasename(); 32 | 33 | if (!$file->isFile() || pathinfo($filepath, PATHINFO_EXTENSION) !== 'xml') { 34 | continue; 35 | } 36 | 37 | $contents = file_get_contents($filepath); 38 | 39 | $matches = []; 40 | preg_match_all('@(.*)(.*)(.*)@', $contents, $matches); 41 | 42 | // Check if any optional parameters exist 43 | if (empty($matches)) { 44 | continue; 45 | } 46 | 47 | // Log optional parameters without default values 48 | // We use the DocBook tag for this task. 49 | foreach ($matches[3] as $index => $match) { 50 | $count_total++; 51 | if (empty($match) || (!str_contains($match, ''))) { 52 | $count_empty++; 53 | // index 2 corresponds to the param, index 1 to the type 54 | $empty[$filepath][$matches[2][$index]] = $matches[1][$index]; 55 | } 56 | } 57 | } 58 | 59 | // This output could be more useful 60 | if (array_key_exists('o', $opts)) { 61 | foreach ($empty as $file => $issues) { 62 | echo $file, ' has ', count($issues), ' optional parameters without initializers:', "\n"; 63 | foreach ($issues as $param => $type) { 64 | echo '- Param "', $param, '" of type "', $type, "\"\n"; 65 | } 66 | } 67 | } 68 | 69 | print "Found $count_total optional parameters, and $count_empty are empty.\n"; 70 | 71 | function usage() { 72 | echo "\nUSAGE:\n"; 73 | echo "$ php {$_SERVER['SCRIPT_FILENAME']} -p /path/to/phpdoc/docs/to/check\n"; 74 | echo " Optional: Add -o to output the results.\n"; 75 | exit; 76 | } 77 | -------------------------------------------------------------------------------- /scripts/translation/lib/CacheFile.php: -------------------------------------------------------------------------------- 1 | | 15 | * +----------------------------------------------------------------------+ 16 | * | Description: Class to handle data persistence. | 17 | * +----------------------------------------------------------------------+ 18 | */ 19 | 20 | require_once __DIR__ . '/all.php'; 21 | 22 | class CacheFile 23 | { 24 | const CACHE_DIR = __DIR__ . '/../.cache'; 25 | 26 | private string $filename; 27 | 28 | function __construct( string $file ) 29 | { 30 | $this->filename = CacheFile::prepareFilename( $file , true ); 31 | } 32 | 33 | public function load( mixed $init = null ) 34 | { 35 | if ( file_exists( $this->filename ) == false ) 36 | return $init; 37 | $data = file_get_contents( $this->filename ); 38 | return unserialize( gzdecode( $data ) ); 39 | } 40 | 41 | public function save( $data ) 42 | { 43 | $contents = gzencode( serialize( $data ) ); 44 | file_put_contents( $this->filename , $contents ); 45 | } 46 | 47 | public static function prepareFilename( string $file , bool $createCacheDirs = false ) 48 | { 49 | if ( str_starts_with( $file , '/' ) ) 50 | return $file; 51 | $outPath = CacheUtil::CACHE_DIR . '/' . dirname( $file ); 52 | $outFile = rtrim( $outPath , '/' ) . '/' . $file; 53 | if ( $createCacheDirs && file_exists( $outPath ) == false ) 54 | mkdir( $outPath , 0777 , true ); 55 | return $outFile; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /scripts/translation/qaxml-pi.php: -------------------------------------------------------------------------------- 1 | | 14 | +----------------------------------------------------------------------+ 15 | 16 | # Description 17 | 18 | Compare processing instructions usage between two XML files. */ 19 | 20 | require_once __DIR__ . '/libqa/all.php'; 21 | 22 | $argv = new ArgvParser( $argv ); 23 | $ignore = new OutputIgnore( $argv ); // may exit. 24 | $argv->complete(); 25 | 26 | $list = SyncFileList::load(); 27 | 28 | foreach ( $list as $file ) 29 | { 30 | $source = $file->sourceDir . '/' . $file->file; 31 | $target = $file->targetDir . '/' . $file->file; 32 | $output = new OutputBuffer( "# qaxml.p" , $target , $ignore ); 33 | 34 | [ $s ] = XmlFrag::loadXmlFragmentFile( $source ); 35 | [ $t ] = XmlFrag::loadXmlFragmentFile( $target ); 36 | 37 | $s = XmlFrag::listNodes( $s , XML_PI_NODE ); 38 | $t = XmlFrag::listNodes( $t , XML_PI_NODE ); 39 | 40 | $s = extractPiData( $s ); 41 | $t = extractPiData( $t ); 42 | 43 | if ( implode( "\n" , $s ) === implode( "\n" , $t ) ) 44 | continue; 45 | 46 | $sideCount = []; 47 | 48 | foreach( $s as $v ) 49 | $sideCount[$v] = [ 0 , 0 ]; 50 | foreach( $t as $v ) 51 | $sideCount[$v] = [ 0 , 0 ]; 52 | 53 | foreach( $s as $v ) 54 | $sideCount[$v][0] += 1; 55 | foreach( $t as $v ) 56 | $sideCount[$v][1] += 1; 57 | 58 | foreach( $sideCount as $k => $v ) 59 | if ( $v[0] != $v[1] ) 60 | $output->addDiff( $k , $v[0] , $v[1] ); 61 | 62 | $output->print(); 63 | } 64 | 65 | function extractPiData( array $list ) 66 | { 67 | $ret = []; 68 | foreach( $list as $elem ) 69 | $ret[] = "{$elem->target} {$elem->data}"; 70 | return $ret; 71 | } 72 | -------------------------------------------------------------------------------- /scripts/translation/qaxml.e.php: -------------------------------------------------------------------------------- 1 | | 15 | * +----------------------------------------------------------------------+ 16 | * | Description: Compare entities usage between XMLs. | 17 | * +----------------------------------------------------------------------+ 18 | */ 19 | 20 | echo "This tool is obsolete and will be REMOVED soon.\n"; 21 | echo "See https://github.com/php/doc-base/blob/master/scripts/translation/README.md\n"; 22 | echo "for alternatives.\n\n". 23 | 24 | require_once __DIR__ . '/lib/all.php'; 25 | 26 | $qalist = QaFileInfo::cacheLoad(); 27 | $outarg = new OutputIgnoreArgv( $argv ); 28 | 29 | foreach ( $qalist as $qafile ) 30 | { 31 | if ( $qafile->sourceHash != $qafile->targetHash ) 32 | continue; 33 | 34 | $source = $qafile->sourceDir . '/' . $qafile->file; 35 | $target = $qafile->targetDir . '/' . $qafile->file; 36 | 37 | $s = XmlUtil::extractEntities( $source ); 38 | $t = XmlUtil::extractEntities( $target ); 39 | 40 | if ( implode( "\n" , $s ) == implode( "\n" , $t ) ) 41 | continue; 42 | 43 | $output = new OutputIgnoreBuffer( $outarg , "qaxml.e: {$target}\n\n" , $target ); 44 | 45 | $match = []; 46 | 47 | foreach( $s as $v ) 48 | $match[$v] = array( 0 , 0 ); 49 | foreach( $t as $v ) 50 | $match[$v] = array( 0 , 0 ); 51 | 52 | foreach( $s as $v ) 53 | $match[$v][0] += 1; 54 | foreach( $t as $v ) 55 | $match[$v][1] += 1; 56 | 57 | foreach( $match as $k => $v ) 58 | { 59 | if ( $v[0] == $v[1] ) 60 | continue; 61 | 62 | $output->add( "* &{$k}; -{$v[1]} +{$v[0]}\n" ); 63 | } 64 | 65 | $output->addLine(); 66 | $output->print(); 67 | } 68 | -------------------------------------------------------------------------------- /scripts/translation/lib/QaFileInfo.php: -------------------------------------------------------------------------------- 1 | | 15 | * +----------------------------------------------------------------------+ 16 | * | Description: Common data for revcheck and QA tools. | 17 | * +----------------------------------------------------------------------+ 18 | */ 19 | 20 | require_once __DIR__ . '/all.php'; 21 | 22 | class QaFileInfo 23 | { 24 | public string $sourceHash; 25 | public string $targetHash; 26 | public string $sourceDir; 27 | public string $targetDir; 28 | public string $file; 29 | public int $days; 30 | 31 | function __construct( string $sourceHash , string $targetHash , string $sourceDir , string $targetDir , string $file , int $days ) 32 | { 33 | $this->sourceHash = $sourceHash; 34 | $this->targetHash = $targetHash; 35 | $this->sourceDir = $sourceDir; 36 | $this->targetDir = $targetDir; 37 | $this->file = $file; 38 | $this->days = $days; 39 | } 40 | 41 | public static function cacheLoad() :array 42 | { 43 | return CacheUtil::load( "" , "QaFileInfo.phps" ); 44 | } 45 | 46 | public static function cacheSave( array $itens ) 47 | { 48 | // PHP serialize() 49 | CacheUtil::save( "" , "QaFileInfo.phps" , $itens ); 50 | 51 | // CSV 52 | $filename = CacheUtil::prepareFilename( "" , "QaFileInfo.csv" , true ); 53 | $fp = fopen( $filename , 'w' ); 54 | foreach( $itens as $item ) 55 | { 56 | $line = array( $item->sourceHash , $item->targetHash , $item->sourceDir , $item->targetDir , $item->file , $item->days ); 57 | fputcsv( $fp , $line, escape: "" ); 58 | } 59 | fclose($fp); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /scripts/translation/libqa/SyncFileList.php: -------------------------------------------------------------------------------- 1 | | 14 | +----------------------------------------------------------------------+ 15 | 16 | # Description 17 | 18 | Generates (and caches) the list of files with TranslatedOk status. */ 19 | 20 | require_once __DIR__ . '/all.php'; 21 | 22 | class SyncFileList 23 | { 24 | static function load() 25 | { 26 | $file = __DIR__ . "/../../../temp/lang"; 27 | if ( ! file_exists( $file ) ) 28 | { 29 | fwrite( STDERR , "Language file not found, run 'doc-base/configure.php'.\n" ); 30 | exit(); 31 | } 32 | 33 | $lang = trim( file_get_contents( $file ) ); 34 | $cacheFilename = __DIR__ . "/../../../temp/qaxml.files.$lang"; 35 | 36 | if ( file_exists( $cacheFilename ) ) 37 | { 38 | return unserialize( gzdecode( file_get_contents( $cacheFilename ) ) ); 39 | } 40 | 41 | $sourceDir = 'en'; 42 | $targetDir = $lang; 43 | 44 | require_once __DIR__ . '/../lib/all.php'; 45 | 46 | $files = new RevcheckFileList( $sourceDir ); 47 | $ret = []; 48 | 49 | foreach( $files->iterator() as $file ) 50 | { 51 | if ( ! file_exists( "$targetDir/{$file->file}" ) ) 52 | continue; 53 | 54 | $item = new SyncFileItem(); 55 | $item->sourceDir = $sourceDir; 56 | $item->targetDir = $targetDir; 57 | $item->file = $file->file; 58 | $ret[] = $item; 59 | } 60 | 61 | if ( $ret === [] ) 62 | throw new Exception( "No files found. Called from wrong directory?" ); 63 | 64 | $contents = gzencode( serialize( $ret ) ); 65 | file_put_contents( $cacheFilename , $contents ); 66 | 67 | return $ret; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /scripts/translation/qaxml-ws.php: -------------------------------------------------------------------------------- 1 | | 14 | +----------------------------------------------------------------------+ 15 | 16 | # Description 17 | 18 | Inspect white space usage inside some known tags. Spurious whitespace 19 | may break manual linking or generate visible artifacts. */ 20 | 21 | require_once __DIR__ . '/libqa/all.php'; 22 | 23 | $argv = new ArgvParser( $argv ); 24 | $ignore = new OutputIgnore( $argv ); // may exit. 25 | $argv->complete(); 26 | 27 | $list = SyncFileList::load(); 28 | 29 | foreach ( $list as $file ) 30 | { 31 | $source = $file->sourceDir . '/' . $file->file; 32 | $target = $file->targetDir . '/' . $file->file; 33 | 34 | whitespaceCheckFile( $source , $ignore ); 35 | whitespaceCheckFile( $target , $ignore ); 36 | } 37 | 38 | function whitespaceCheckFile( string $filename , OutputIgnore $ignore ) 39 | { 40 | if ( file_exists( $filename ) == false ) 41 | return; 42 | 43 | $output = new OutputBuffer( "# qaxml.w" , $filename , $ignore ); 44 | 45 | [ $xml , $_ , $_ ] = XmlFrag::loadXmlFragmentFile( $filename ); 46 | $nodes = XmlFrag::listNodes( $xml , XML_ELEMENT_NODE ); 47 | 48 | foreach( $nodes as $node ) 49 | { 50 | switch ( $node->nodeName ) 51 | { 52 | case "classname": 53 | case "constant": 54 | case "function": 55 | case "methodname": 56 | case "varname": 57 | $text = $node->nodeValue; 58 | $trim = trim( $text ); 59 | if ( $text != $trim ) 60 | { 61 | $output->addLine(); 62 | $output->add( " {$node->nodeName} {$trim}\n" ); 63 | } 64 | break; 65 | } 66 | } 67 | 68 | $output->print(); 69 | } 70 | -------------------------------------------------------------------------------- /scripts/en.pws: -------------------------------------------------------------------------------- 1 | personal_ws-1.1 en 242 2 | ISAPI 3 | plugin 4 | UDM 5 | HTTPS 6 | https 7 | dBase 8 | httpd 9 | UDP 10 | pspell 11 | Borland 12 | Google 13 | mcrypt 14 | zlib 15 | RPC 16 | SQL 17 | Bcc 18 | conf 19 | CMYK 20 | RPN 21 | EZMLM 22 | bzip 23 | iPlanet 24 | GMP 25 | cygwin 26 | ClibPDF 27 | bezier 28 | xml 29 | PostgreSQL 30 | Solaris 31 | XPath 32 | builtin 33 | versioning 34 | GPG 35 | JPEG 36 | jpeg 37 | jpg 38 | ODBC 39 | odbc 40 | iODBC 41 | GPL 42 | mnoGoSearch 43 | mnogosearch 44 | README 45 | prerelease 46 | Zend 47 | FAM 48 | SPX 49 | stdin 50 | TCL 51 | servlet 52 | php 53 | CRC 54 | crc 55 | gdb 56 | stderr 57 | cron 58 | stdout 59 | WDDX 60 | SNMP 61 | Sablotron 62 | towards 63 | gzip 64 | JSP 65 | MCVE 66 | mcve 67 | GTK 68 | Gtk 69 | TLS 70 | CSR 71 | mhash 72 | XSL 73 | SESAM 74 | iconv 75 | msession 76 | gif 77 | MCAL 78 | mcal 79 | SDK 80 | PCNTL 81 | pcntl 82 | EGPCS 83 | Xitami 84 | Informix 85 | LF 86 | gcc 87 | CGI 88 | cgi 89 | DNS 90 | CLI 91 | CCL 92 | MacOS 93 | FI 94 | hw 95 | gz 96 | JS 97 | CSS 98 | gd 99 | GID 100 | MX 101 | Ovrimos 102 | ovrimos 103 | png 104 | NUL 105 | NUM 106 | MSIE 107 | DSSSL 108 | ZZIPlib 109 | dir 110 | LDAP 111 | ldap 112 | Inprise 113 | EOF 114 | NIS 115 | SHA 116 | PEM 117 | openssl 118 | awk 119 | UX 120 | IRC 121 | func 122 | url 123 | EOL 124 | ini 125 | DTD 126 | ip 127 | API 128 | OOP 129 | api 130 | PWS 131 | NULLs 132 | pid 133 | SWF 134 | Mozilla 135 | fbsql 136 | IIS 137 | ascii 138 | OCI 139 | IDE 140 | oid 141 | UID 142 | Verisign 143 | CRLF 144 | binutils 145 | VBScript 146 | unserialized 147 | TTF 148 | fopen 149 | SSL 150 | ssl 151 | RSA 152 | SAPI 153 | XP 154 | DLL 155 | dll 156 | PHP's 157 | xmlrpc 158 | ibase 159 | FDF 160 | fdf 161 | unescaped 162 | undefine 163 | GmbH 164 | NTFS 165 | VC 166 | mbstring 167 | NSAPI 168 | online 169 | inline 170 | unix 171 | XHTML 172 | NNTP 173 | PECL 174 | onload 175 | hmac 176 | PGP 177 | pcre 178 | YAZ 179 | yaz 180 | ActiveX 181 | IRCG 182 | unziped 183 | Postgres 184 | icap 185 | validator 186 | shmop 187 | exe 188 | ncurses 189 | UCD 190 | expat 191 | IMAP 192 | JScript 193 | internet 194 | IPv 195 | PREG 196 | SQLite 197 | sqlite 198 | concatenator 199 | endian 200 | Sybase 201 | sybase 202 | untar 203 | inode 204 | PDF 205 | pdf 206 | html 207 | IPX 208 | IPC 209 | PKCS 210 | symlink 211 | RGB 212 | rgb 213 | XSLT 214 | xslt 215 | http 216 | precompiled 217 | JVM 218 | POSIX 219 | posix 220 | APIs 221 | CVS 222 | CCVS 223 | MySQL 224 | mysql 225 | msql 226 | mSQL 227 | MSSQL 228 | mssql 229 | mysqli 230 | MySQLi 231 | WBMP 232 | BMP 233 | symlinks 234 | uncheck 235 | OSX 236 | UTF 237 | UDF 238 | utf 239 | regex 240 | -------------------------------------------------------------------------------- /chm/common.php: -------------------------------------------------------------------------------- 1 | |[^a-zA-Z1-9][^>]*>)/Ue", "preg_replace('/[\r\n]{1,2}/U', ' ', \"<\$1 \$2\")", file_get_contents($filename)); 15 | } else { 16 | $buf = preg_replace("/[\r|\n]{1,2}/U", " ", file_get_contents($filename)); 17 | } 18 | $charset = detectDocumentCharset($buf); 19 | 20 | if ($charset === false) $charset = "UTF-8"; 21 | 22 | if ($charset != $INTERNAL_CHARSET) { 23 | if (function_exists("iconv")) { 24 | $buf = iconv($charset, $INTERNAL_CHARSET, $buf); 25 | } elseif (function_exists("mb_convert_encoding")) { 26 | $buf = mb_convert_encoding($buf, $INTERNAL_CHARSET, $charset); 27 | } elseif (preg_match("/^UTF-?8$/i", $INTERNAL_CHARSET) && preg_match("/^(ISO-8859-1|WINDOWS-1252)$/i", $charset)) { 28 | $buf = utf8_encode($buf); 29 | } else { 30 | die("charset conversion function is not available."); 31 | } 32 | } 33 | return $buf; 34 | } 35 | 36 | function fputs_wrapper($fp, $str) 37 | { 38 | fputs($fp, convertCharset($str)); 39 | } 40 | 41 | function convertCharset($buf) 42 | { 43 | global $LANGUAGE, $LANGUAGES, $INTERNAL_CHARSET; 44 | 45 | $charset = $LANGUAGES[$LANGUAGE]['preferred_charset']; 46 | 47 | if ($charset != $INTERNAL_CHARSET) { 48 | if (function_exists("iconv")) { 49 | $buf = iconv($INTERNAL_CHARSET, "$charset//TRANSLIT", $buf); 50 | } elseif (function_exists("mb_convert_encoding")) { 51 | $buf = mb_convert_encoding($buf, $charset, $INTERNAL_CHARSET); 52 | } elseif (preg_match("/^UTF-?8$/i", $INTERNAL_CHARSET) && preg_match("/^(ISO-8859-1|WINDOWS-1252)$/i", $charset)) { 53 | $buf = utf8_decode($buf); 54 | } else { 55 | die("$LANGUAGE locale is not supported."); 56 | } 57 | } 58 | return $buf; 59 | } // oneLiner() function end 60 | 61 | // Returns the name of character set in the given document 62 | function detectDocumentCharset($doc) 63 | { 64 | if (preg_match('/]+CHARSET=["\'\s]?([\w\d-]+)["\'\s]?\s*>/iS', $doc, $reg)) { 65 | return $reg[1]; 66 | } 67 | return false; 68 | } 69 | 70 | function setDocumentCharset($doc, $charset) 71 | { 72 | return preg_replace("/()/iU", "\$1$charset\$3", $doc); 73 | } 74 | ?> 75 | 76 | -------------------------------------------------------------------------------- /scripts/translation/lib/RevcheckIgnore.php: -------------------------------------------------------------------------------- 1 | | 15 | * +----------------------------------------------------------------------+ 16 | * | Description: Files ignored on translation tree. | 17 | * +----------------------------------------------------------------------+ 18 | */ 19 | 20 | require_once __DIR__ . '/all.php'; 21 | 22 | class RevcheckIgnore 23 | { 24 | public static function ignore( $filename ) : bool 25 | { 26 | // Ignore dot files 27 | 28 | if ( $filename[0] == '.' ) 29 | return true; 30 | 31 | // Ignore files other than xml assets 32 | 33 | if ( ( str_ends_with( $filename , '.xml' ) || str_ends_with( $filename , '.ent' ) ) == false ) 34 | return true; 35 | 36 | // Ignore autogenerated files 37 | 38 | if ( str_starts_with( $filename , "entities." ) ) 39 | return true; 40 | if ( str_contains( $filename , "/entities." ) ) 41 | return true; 42 | if ( str_contains( $filename , "/versions.xml" ) ) 43 | return true; 44 | 45 | // Only in English, autogenerated, marked not translatable 46 | 47 | if ( $filename == "contributors.ent" ) 48 | return true; 49 | if ( $filename == "contributors.xml" ) 50 | return true; 51 | if ( $filename == "appendices/license.xml" ) 52 | return true; 53 | if ( $filename == "appendices/extensions.xml" ) 54 | return true; 55 | if ( $filename == "appendices/reserved.constants.xml" ) 56 | return true; 57 | if ( $filename == "reference/datetime/timezones.xml" ) 58 | return true; 59 | 60 | // Only in translations 61 | 62 | if ( $filename == "translation.xml" ) 63 | return true; 64 | 65 | // At least, do not ignore 66 | return false; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /scripts/translation/qaxml.w.php: -------------------------------------------------------------------------------- 1 | | 15 | * +----------------------------------------------------------------------+ 16 | * | Description: Checks for ws that may cause render trouble. | 17 | * +----------------------------------------------------------------------+ 18 | */ 19 | 20 | echo "This tool is obsolete and will be REMOVED soon.\n"; 21 | echo "See https://github.com/php/doc-base/blob/master/scripts/translation/README.md\n"; 22 | echo "for alternatives.\n\n". 23 | 24 | require_once __DIR__ . '/lib/all.php'; 25 | 26 | $qalist = QaFileInfo::cacheLoad(); 27 | $outarg = new OutputIgnoreArgv( $argv ); 28 | 29 | foreach ( $qalist as $qafile ) 30 | { 31 | $source = $qafile->sourceDir . '/' . $qafile->file; 32 | $target = $qafile->targetDir . '/' . $qafile->file; 33 | 34 | whitespaceCheckFile( $source ); 35 | whitespaceCheckFile( $target ); 36 | } 37 | 38 | function whitespaceCheckFile( string $filename ) 39 | { 40 | if ( file_exists( $filename ) == false ) 41 | return; 42 | 43 | global $outarg; 44 | $output = new OutputIgnoreBuffer( $outarg , "qaxml.w: {$filename}\n\n" , $filename ); 45 | 46 | $xml = XmlUtil::loadFile( $filename ); 47 | $tags = XmlUtil::listNodeType( $xml , XML_ELEMENT_NODE ); 48 | 49 | foreach( $tags as $node ) 50 | { 51 | switch ( $node->nodeName ) 52 | { 53 | case "classname": 54 | case "constant": 55 | case "function": 56 | case "methodname": 57 | case "varname": 58 | $text = $node->nodeValue; 59 | $trim = trim( $text ); 60 | if ( $text != $trim ) 61 | { 62 | $output->addLine(); 63 | $output->add( " {$node->nodeName} {$trim}\n" ); 64 | } 65 | break; 66 | } 67 | } 68 | 69 | $output->print(); 70 | } 71 | -------------------------------------------------------------------------------- /scripts/translation/qaxml-attributes.php: -------------------------------------------------------------------------------- 1 | | 14 | +----------------------------------------------------------------------+ 15 | 16 | # Description 17 | 18 | Compare attributes usage between two XML leaf/fragment files. */ 19 | 20 | require_once __DIR__ . '/libqa/all.php'; 21 | 22 | $argv = new ArgvParser( $argv ); 23 | $ignore = new OutputIgnore( $argv ); // may exit. 24 | $urgent = $argv->consume( "--urgent" ) != null; 25 | 26 | $list = SyncFileList::load(); 27 | $argv->complete(); 28 | 29 | foreach ( $list as $file ) 30 | { 31 | $source = $file->sourceDir . '/' . $file->file; 32 | $target = $file->targetDir . '/' . $file->file; 33 | $output = new OutputBuffer( "# qaxml.a" , $target , $ignore ); 34 | 35 | [ $s , $_ , $_ ] = XmlFrag::loadXmlFragmentFile( $source ); 36 | [ $t , $_ , $_ ] = XmlFrag::loadXmlFragmentFile( $target ); 37 | 38 | $s = XmlFrag::listNodes( $s , XML_ELEMENT_NODE ); 39 | $t = XmlFrag::listNodes( $t , XML_ELEMENT_NODE ); 40 | 41 | $s = extractTriple( $s ); 42 | $t = extractTriple( $t ); 43 | 44 | if ( implode( "\n" , $s ) == implode( "\n" , $t ) ) 45 | continue; 46 | 47 | $sideCount = []; 48 | 49 | foreach( $s as $v ) 50 | $sideCount[$v] = [ 0 , 0 ]; 51 | foreach( $t as $v ) 52 | $sideCount[$v] = [ 0 , 0 ]; 53 | 54 | foreach( $s as $v ) 55 | $sideCount[$v][0] += 1; 56 | foreach( $t as $v ) 57 | $sideCount[$v][1] += 1; 58 | 59 | foreach( $sideCount as $k => $v ) 60 | if ( $v[0] != $v[1] ) 61 | $output->addDiff( $k , $v[0] , $v[1] ); 62 | 63 | if ( $urgent ) 64 | if ( $output->contains( "xml:id" ) == false ) 65 | continue; 66 | 67 | $output->print(); 68 | } 69 | 70 | function extractTriple( array $list ) 71 | { 72 | $ret = []; 73 | foreach( $list as $elem ) 74 | foreach( $elem->attributes as $attrib ) 75 | $ret[] = "{$elem->nodeName} {$attrib->nodeName} {$attrib->nodeValue}"; 76 | return $ret; 77 | } 78 | -------------------------------------------------------------------------------- /docs/joining.md: -------------------------------------------------------------------------------- 1 | # Joining the team 2 | 3 | Joining the PHP Documentation team is a simple process, but a process nonetheless. 4 | You don't have to the join the team to [contribute](contributing.md), 5 | but joining the team can be a way to get more involved in the process 6 | and help out with larger projects. 7 | 8 | ## Write to a mailing list 9 | Because official communication is done there, you should write to the proper list. 10 | Say "Hi" and what you're interested in doing. You may feel more comfortable lurking 11 | for a while, or reading the archives, but ultimately let the list know who you are. 12 | 13 | ### For authors 14 | You should send your message to the `phpdoc@lists.php.net` mailing list. You 15 | will need to subscribe to the list in order to send email to it. You can find 16 | [archives of the list on news-web.php.net](https://news-web.php.net/php.doc), 17 | and there is also a form to subscribe to the list there. 18 | 19 | You can subscribe the regular version of the list (you get every 20 | message as it is sent), the digest version (you'll get a daily-or-so 21 | mail containing all of the new messages to the list), or the "no mail" 22 | version which allows you to send a message but doesn't send you any emails 23 | (useful if you just read through the web archive or an NNTP client). 24 | 25 | ### For translators 26 | You should send your message to the appropriate `doc-{LANG}@lists.php.net` mailing list. 27 | 28 | ## Informal discussion 29 | The mailing lists above are the primary communication forum. In particular, 30 | decisions and plans should be made on the list so they are recorded in the 31 | archives. 32 | 33 | However for more realtime and/or informal chat, some doc authors hang out in 34 | "Room 11" on Stackoverflow Chat: https://chat.stackoverflow.com/rooms/11/php 35 | 36 | Some authors hang out in the `#php-doc` channel on IRC on the 37 | https://Libera.Chat network, which is also bridged to the Discord server run 38 | by the PHP Community Foundation, available at https://phpc.chat. 39 | 40 | ## Create a doc patch or three 41 | This step is required to show us that you are a real human, you want to do 42 | some work and in general know how to do this. 43 | 44 | The simplest way to get started is by using GitHub, to create and send Pull Requests 45 | to [php/doc-en][doc-en] or php/doc-{LANG} for translations. 46 | 47 | Your Pull Requests will be then reviewed and accepted by someone with Git commit access. 48 | 49 | ## Obtaining Git commit access 50 | If you plan to contribute to the manual regularly and want to help process 51 | contributions from others, you might want to request to be added to the 52 | documentation team (or a translation team) on GitHub, which you can do on the 53 | email lists. 54 | 55 | To be clear: you don't need Git commit access to start contributing to the 56 | documentation! Anyone with a GitHub account (which is free) can submit Pull 57 | Requests to the documentation repositories. 58 | 59 | [doc-en]: https://github.com/php/doc-en 60 | -------------------------------------------------------------------------------- /scripts/translation/lib/RevcheckFileList.php: -------------------------------------------------------------------------------- 1 | | 15 | * +----------------------------------------------------------------------+ 16 | * | Description: General file transversal, ordered file listing. | 17 | * +----------------------------------------------------------------------+ 18 | */ 19 | 20 | require_once __DIR__ . '/all.php'; 21 | 22 | class RevcheckFileList 23 | { 24 | private $list = []; 25 | 26 | function __construct( $lang ) 27 | { 28 | $this->loadTree( $lang ); 29 | } 30 | 31 | function get( $file ): RevcheckFileItem|null 32 | { 33 | return $this->list[ $file ] ?? null; 34 | } 35 | 36 | function iterator(): Iterator 37 | { 38 | return new ArrayIterator( $this->list ); 39 | } 40 | 41 | function loadTree( $lang ) 42 | { 43 | $dir = new \DirectoryIterator( $lang ); 44 | if ( $dir === false ) 45 | die( "$lang is not a directory.\n" ); 46 | $cwd = getcwd(); 47 | chdir( $lang ); 48 | $this->loadTreeRecurse( $lang , "" ); 49 | chdir( $cwd ); 50 | } 51 | 52 | function loadTreeRecurse( $lang , $path ) 53 | { 54 | $todoDirs = []; 55 | $dir = new DirectoryIterator( $path == "" ? "." : $path ); 56 | if ( $dir === false ) 57 | die( "$path is not a directory.\n" ); 58 | 59 | foreach( $dir as $entry ) 60 | { 61 | $name = $entry->getFilename(); 62 | $key = ltrim( $path . '/' . $name , '/' ); 63 | if ( $name[0] == '.' ) 64 | continue; 65 | if ( $entry->isDir() ) 66 | { 67 | $todoDirs[] = $key; 68 | continue; 69 | } 70 | 71 | if ( RevcheckIgnore::ignore( $key ) ) 72 | continue; 73 | $file = new RevcheckFileItem( $key , $entry->getSize() ); 74 | $this->list[ $key ] = $file; 75 | } 76 | 77 | sort( $todoDirs ); 78 | foreach( $todoDirs as $path ) 79 | $this->loadTreeRecurse( $lang , $path ); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /scripts/grep-files.php: -------------------------------------------------------------------------------- 1 | #!/usr/bin/php -q 2 | | 16 | +----------------------------------------------------------------------+ 17 | 18 | $Id$ 19 | */ 20 | 21 | if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { 22 | echo "This script requires a non-Windows operating system.\n"; 23 | exit; 24 | } 25 | 26 | $editor = getenv('EDITOR'); 27 | 28 | if ($_SERVER['argc'] == 2 && 29 | in_array($_SERVER['argv'][1], array('--help', '-help', '-h', '-?')) 30 | || 31 | $_SERVER['argc'] < 2) { 32 | 33 | echo "\nFind and edit files by grepping for a case insensitive string.\n"; 34 | echo "I will open EDITOR if it's set, and the [language directory] is optional.\n\n"; 35 | echo "Usage: {$_SERVER['argv'][0]} [langdir]\n"; 36 | echo "Example: {$_SERVER['argv'][0]} 'PHP3' en\n"; 37 | if ($editor) { 38 | echo "Note: Your EDITOR is set to: {$editor}\n\n"; 39 | } else { 40 | echo "Note: You do not have an EDITOR set so I will output a string of files\n\n"; 41 | } 42 | exit; 43 | } 44 | 45 | $langdir = ''; 46 | if (!empty($_SERVER['argv'][2])) { 47 | $dir = trim($_SERVER['argv'][2]); 48 | if (is_dir($dir)) { 49 | $langdir = rtrim($dir, '/') . '/'; 50 | } else { 51 | echo "INFO: The desired language directory ({$dir}) does not exist. Skipping...\n"; 52 | } 53 | } 54 | 55 | $search_str = trim($_SERVER['argv'][1]); 56 | $output = trim(shell_exec("egrep --exclude=\*.svn\* -i -r '{$search_str}' {$langdir}* ")); 57 | 58 | if (empty($output)) { 59 | echo "INFO: No matches for string '{$search_str}'\n"; 60 | exit; 61 | } 62 | 63 | $files = array(); 64 | foreach (explode("\n", $output) as $line) { 65 | 66 | $filename = trim(substr($line, 0, strpos($line, ':'))); 67 | $ext = pathinfo($filename, PATHINFO_EXTENSION); 68 | 69 | if (($ext === 'xml' || $ext === 'ent') && $filename[0] !== '.') { 70 | $files[$filename] = 'open'; 71 | } 72 | } 73 | 74 | if (empty($files)) { 75 | echo "INFO: No matches for string '{$search_str}'\n"; 76 | exit; 77 | } 78 | 79 | $files_str = implode(' ', array_keys($files)); 80 | 81 | if ($editor) { 82 | shell_exec($editor . ' ' . $files_str); 83 | } else { 84 | echo $files_str; 85 | } 86 | -------------------------------------------------------------------------------- /scripts/mk_ini_set_table.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | # Quick hack to make a table of PHP options 4 | # and where they can be changed 5 | # Uses GNU grep and GNU awk 6 | # Author: Jesus M. Castagnetto 7 | # Created: Mon Mar 19 04:57:02 PST 2001 8 | # Updated: Thu Apr 25 11:42:26 PDT 2002 9 | # - look through all INI_ containing files 10 | # - save table in the new split dir for the function 11 | # Updated: Wed Nov 20 18:16:12 PST 2002 12 | # - rearrange the order of the tables, put the INI_* definitions first. 13 | 14 | cfiles=`grep -rl INI_ ../php4/*` 15 | ini_set_table="en/reference/info/functions/ini_set_table"; 16 | 17 | awk 'BEGIN { 18 | print ""; 19 | print " "; 20 | print " The INI_* constants used in the table below are defined as follows:"; 21 | print " "; 22 | print " "; 23 | print " "; 24 | print " Constant"; 25 | print " Value"; 26 | print " Meaning"; 27 | print " "; 28 | print " "; 29 | print " "; 30 | print " "; 31 | print " INI_USER"; 32 | print " 1"; 33 | print " Entry can be set in user scripts"; 34 | print " "; 35 | print " "; 36 | print " INI_PERDIR"; 37 | print " 2"; 38 | print " Entry can be set in .htaccess"; 39 | print " "; 40 | print " "; 41 | print " INI_SYSTEM"; 42 | print " 4"; 43 | print " Entry can be set in php.ini or"; 44 | print " httpd.conf"; 45 | print " "; 46 | print " "; 47 | print " INI_ALL"; 48 | print " 7"; 49 | print " Entry can be set anywhere"; 50 | print " "; 51 | print " "; 52 | print "
"; 53 | print "
"; 54 | print "
"; 55 | print "\n Configuration options" 56 | print " "; 57 | print " "; 58 | print " "; 59 | print " Name"; 60 | print " Default"; 61 | print " Changeable"; 62 | print " "; 63 | print " "; 64 | print " "; 65 | } 66 | $0 ~ /INI_.*\(/ && $0 !~ /^static/ && $0 !~ /INI_(BEGIN|END)/ { 67 | nf = split($0,tmp,","); 68 | 69 | varname = substr(tmp[1], index(tmp[1], "\"")); 70 | gsub("\"", "", varname); 71 | 72 | vardef = tmp[2]; 73 | gsub("(\t| )+", "", vardef); 74 | #if (index(vardef, "\"")) 75 | # gsub("\"", "", vardef); 76 | 77 | varmod = tmp[3]; 78 | gsub("(\t| )+", "", varmod); 79 | 80 | print " "; 81 | print " " varname "" 82 | print " " vardef "" 83 | print " " varmod "" 84 | print " "; 85 | }; 86 | END { 87 | print " "; 88 | print " "; 89 | print "
"; 90 | }' $cfiles > $ini_set_table 91 | 92 | ls -l $ini_set_table 93 | -------------------------------------------------------------------------------- /scripts/translation/qaxml.p.php: -------------------------------------------------------------------------------- 1 | | 15 | * +----------------------------------------------------------------------+ 16 | * | Description: Compare PIs usage between XMLs. | 17 | * +----------------------------------------------------------------------+ 18 | */ 19 | 20 | echo "This tool is obsolete and will be REMOVED soon.\n"; 21 | echo "See https://github.com/php/doc-base/blob/master/scripts/translation/README.md\n"; 22 | echo "for alternatives.\n\n". 23 | 24 | require_once __DIR__ . '/lib/all.php'; 25 | 26 | $qalist = QaFileInfo::cacheLoad(); 27 | 28 | foreach ( $qalist as $qafile ) 29 | { 30 | if ( $qafile->file == "bookinfo.xml" ) 31 | continue; 32 | if ( $qafile->sourceHash != $qafile->targetHash ) 33 | continue; 34 | 35 | $source = $qafile->sourceDir . '/' . $qafile->file; 36 | $target = $qafile->targetDir . '/' . $qafile->file; 37 | 38 | $s = XmlUtil::loadFile( $source ); 39 | $t = XmlUtil::loadFile( $target ); 40 | 41 | $s = XmlUtil::listNodeType( $s , XML_PI_NODE ); 42 | $t = XmlUtil::listNodeType( $t , XML_PI_NODE ); 43 | 44 | $s = extractPiData( $s ); 45 | $t = extractPiData( $t ); 46 | 47 | if ( implode( "\n" , $s ) == implode( "\n" , $t ) ) 48 | continue; 49 | 50 | $header = true; 51 | $match = []; 52 | 53 | foreach( $s as $v ) 54 | $match[$v] = array( 0 , 0 ); 55 | foreach( $t as $v ) 56 | $match[$v] = array( 0 , 0 ); 57 | 58 | foreach( $s as $v ) 59 | $match[$v][0] += 1; 60 | foreach( $t as $v ) 61 | $match[$v][1] += 1; 62 | 63 | foreach( $match as $k => $v ) 64 | { 65 | if ( $v[0] == $v[1] ) 66 | continue; 67 | 68 | if ( $header ) 69 | { 70 | print "qaxml.p: {$target}\n\n"; 71 | $header = false; 72 | } 73 | 74 | print "* {$k} -{$v[1]} +{$v[0]}\n"; 75 | } 76 | 77 | if ( ! $header ) 78 | print "\n"; 79 | } 80 | 81 | function extractPiData( array $list ) 82 | { 83 | $ret = []; 84 | foreach( $list as $elem ) 85 | $ret[] = "{$elem->target} {$elem->data}"; 86 | return $ret; 87 | } 88 | -------------------------------------------------------------------------------- /scripts/xml-check.php: -------------------------------------------------------------------------------- 1 | #!/usr/bin/php 2 | | 16 | +----------------------------------------------------------------------+ 17 | 18 | $Id$ 19 | */ 20 | 21 | if (!isset($_SERVER["argv"][1])) { 22 | echo "Purpose: Check XML syntax of single PHP manual file.\n"; 23 | echo "Usage: xml-check.php filename.xml [xmllint-command]\n"; 24 | echo "Note: Links are not checked.\n"; 25 | exit(); 26 | } 27 | 28 | $file = file_get_contents($_SERVER["argv"][1]); 29 | $xmllint = (isset($_SERVER["argv"][2]) ? $_SERVER["argv"][2] : "xmllint"); 30 | $root = str_replace('\\', '/', dirname(__FILE__)); 31 | $root = substr($root, 0, strrpos($root, '/')); 32 | $realpath = str_replace('\\', '/', realpath($_SERVER["argv"][1])); 33 | $example_filename = "$root/xml-check.xml"; 34 | $rootpos = strlen($root) + 1; 35 | $language = substr($realpath, $rootpos, strpos($realpath, '/', $rootpos) - $rootpos); 36 | $header = preg_replace('~.*(]*>)(.*)~s', "\\1$header" . (!preg_match("~Example\\2\n" : "\\2") . "\n\n", $file); 40 | $fp = fopen($example_filename, "wb"); 41 | fwrite($fp, $file); 42 | fclose($fp); 43 | 44 | passthru("XMLLINT_INDENT=' ' $xmllint --noent --noout --encode UTF-8 --format --valid $example_filename 2> $example_filename.out"); // xmllint outputs to stderr which is not catched by shell_exec, 2> &1 doesn't work on Windows 45 | $errors = file_get_contents("$example_filename.out"); 46 | $errors = preg_replace("~.*validity error : IDREF attribute linkend references an unknown ID.*\n.*\n.*\n~", "", $errors); 47 | $errors = str_replace($example_filename, $_SERVER["argv"][1], $errors); 48 | 49 | if (empty($errors)) { 50 | echo "Success: Your file passed this XML check, do consider running 'make test' as well.\n"; 51 | } else { 52 | echo "Errors: The following XML error exist:\n"; 53 | echo $errors; 54 | } 55 | 56 | //~ unlink("$example_filename"); 57 | unlink("$example_filename.out"); 58 | ?> 59 | -------------------------------------------------------------------------------- /scripts/build-chms-history.php: -------------------------------------------------------------------------------- 1 | | 15 | * +----------------------------------------------------------------------+ 16 | * 17 | * $Id$ 18 | */ 19 | 20 | 21 | /** 22 | * This script rebuilds build.log used by build-chms.php ($build_history) 23 | * without actually rebuilding the CHM files 24 | */ 25 | 26 | /** 27 | * Configuration 28 | */ 29 | include_once __DIR__ .'/build-chms-config.php'; 30 | 31 | /** 32 | * The languages to build are retrieved from https://svn.php.net/repository/web/php/trunk/include/languages.inc 33 | */ 34 | if (file_exists(__DIR__ . '\\languages.inc')) 35 | { 36 | unlink(__DIR__ . '\\languages.inc'); 37 | } 38 | 39 | execute_task('Get list of online languages', PATH_WGET, '--debug --verbose --no-check-certificate https://svn.php.net/repository/web/php/trunk/include/languages.inc --output-document=' . __DIR__ . '\\languages.inc', false); 40 | 41 | if (file_exists(__DIR__ . '\\languages.inc')) 42 | { 43 | include_once __DIR__ . '\\languages.inc'; 44 | } 45 | 46 | /** 47 | * Always build English first. 48 | */ 49 | unset($ACTIVE_ONLINE_LANGUAGES['en']); 50 | ksort($ACTIVE_ONLINE_LANGUAGES); 51 | 52 | $ACTIVE_ONLINE_LANGUAGES = array('en' => 'English') + $ACTIVE_ONLINE_LANGUAGES; 53 | 54 | /** 55 | * Hold the results of this build 56 | */ 57 | $build_history = array(); 58 | 59 | 60 | foreach($ACTIVE_ONLINE_LANGUAGES as $lang_code => $language) 61 | { 62 | $chm_filename = PATH_CHM . '\\' . 'php_manual_' . $lang_code . '.chm'; 63 | $e_chm_filename = PATH_CHM . '\\' . 'php_enhanced_' . $lang_code . '.chm'; 64 | 65 | if(is_file($chm_filename)) 66 | { 67 | $build_history[] = array('php_manual_' . $lang_code . '.chm', md5_file($chm_filename), filemtime($chm_filename)); 68 | } 69 | 70 | if(is_file($e_chm_filename)) 71 | { 72 | $build_history[] = array('php_enhanced_' . $lang_code . '.chm', md5_file($e_chm_filename), filemtime($e_chm_filename)); 73 | } 74 | } 75 | 76 | /** 77 | * Save build history 78 | */ 79 | file_put_contents(PATH_CHM . '\\build.log', implode(PHP_EOL, array_map(function($single_build) 80 | { 81 | return implode("\t", $single_build); 82 | }, $build_history))); 83 | 84 | echo(date('r') . ' Done!'); 85 | ?> -------------------------------------------------------------------------------- /scripts/translation/libqa/ArgvParser.php: -------------------------------------------------------------------------------- 1 | | 14 | +----------------------------------------------------------------------+ 15 | 16 | # Description 17 | 18 | This class coordinates and centrailzes control for $argv command line 19 | parameters, used between vairous classes. */ 20 | 21 | class ArgvParser 22 | { 23 | private array $argv; 24 | private array $used; 25 | 26 | public function __construct( array $argv ) 27 | { 28 | $this->argv = array_values( array_filter( $argv ) ); 29 | $this->used = array_fill( 0 , count( $argv ) , false ); 30 | } 31 | 32 | public function use( string $arg ) : void 33 | { 34 | foreach ( $this->argv as $pos => $value ) 35 | if ( $arg == $value && $this->used[ $pos ] == false ) 36 | { 37 | $this->used[ $pos ] = true; 38 | return; 39 | } 40 | throw new Exception( "Unused '$arg' not found." ); 41 | } 42 | 43 | public function consume( string $equals = null , string $prefix = null , int $position = -1 ) : string|null 44 | { 45 | $args = $this->argv; 46 | foreach ( $args as $pos => $arg ) 47 | { 48 | if ( $arg == null ) 49 | continue; 50 | 51 | $foundByEquals = $equals != null && $arg == $equals; 52 | $foundByPrefix = $prefix != null && str_starts_with( $arg , $prefix ); 53 | $foundByPosition = $position == $pos; 54 | 55 | if ( $foundByEquals || $foundByPrefix || $foundByPosition ) 56 | { 57 | $this->argv[ $pos ] = null; 58 | $this->used[ $pos ] = true; 59 | 60 | if ( $foundByPrefix ) 61 | return substr( $arg , strlen( $prefix ) ); 62 | 63 | return $arg; 64 | } 65 | } 66 | 67 | return null; 68 | } 69 | 70 | public function complete() : void 71 | { 72 | foreach ( $this->argv as $pos => $arg ) 73 | if ( $this->used[ $pos ] == false ) 74 | fwrite( STDERR , "Unknown argument: {$arg}\n\n" ); 75 | } 76 | 77 | public function residual() : array 78 | { 79 | return array_filter( $this->argv ); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /scripts/translation/lib/RevcheckFileItem.php: -------------------------------------------------------------------------------- 1 | | 15 | * +----------------------------------------------------------------------+ 16 | * | Description: General data of a file in a documentation tree. | 17 | * +----------------------------------------------------------------------+ 18 | */ 19 | 20 | require_once __DIR__ . '/all.php'; 21 | 22 | class RevcheckFileItem 23 | { 24 | public string $file = ""; // from fs 25 | public int $size = 0 ; // from fs 26 | public int $date = 0 ; // from vcs, source only, date of head or diff commit 27 | public string $hashLast = ""; // derived by addGitLogData 28 | public string $hashDiff = ""; // derived by addGitLogData, isSyncHash 29 | 30 | public RevcheckStatus $status; // target only 31 | public RevtagInfo|null $revtag; // target only 32 | 33 | private array $hashList; // source only 34 | private bool $hashStop; // source only 35 | 36 | function __construct( string $file , int $size ) 37 | { 38 | $this->file = $file; 39 | $this->size = $size; 40 | $this->date = 0; 41 | $this->status = RevcheckStatus::Untranslated; 42 | $this->revtag = null; 43 | $this->hashList = []; 44 | $this->hashStop = false; 45 | } 46 | 47 | public function addGitLogData( string $hash , string $date , bool $skip ) : void 48 | { 49 | // Accumulates valid hashes for RevcheckStatus::TranslatedOk status. 50 | // This includes topmost runs of [skip-revcheck] tags and one normal, 51 | // unmarked hash. Stop after first normal hash is found. 52 | 53 | if ( $this->hashStop ) 54 | return; 55 | 56 | $this->hashList[] = $hash; 57 | 58 | if ( $this->hashLast == "" ) 59 | { 60 | $this->date = $date; 61 | $this->hashLast = $hash; 62 | } 63 | 64 | if ( $skip ) 65 | $this->hashDiff = $hash; 66 | else 67 | $this->hashStop = true; 68 | } 69 | 70 | public function isSyncHash( $hash ) : bool 71 | { 72 | $sync = in_array( $hash , $this->hashList ); 73 | if ( $sync ) 74 | $this->hashDiff = $hash; 75 | return $sync; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /scripts/translation/qaxml.a.php: -------------------------------------------------------------------------------- 1 | | 15 | * +----------------------------------------------------------------------+ 16 | * | Description: Compare attributes between XMLs. | 17 | * +----------------------------------------------------------------------+ 18 | */ 19 | 20 | echo "This tool is obsolete and will be REMOVED soon.\n"; 21 | echo "See https://github.com/php/doc-base/blob/master/scripts/translation/README.md\n"; 22 | echo "for alternatives.\n\n". 23 | 24 | require_once __DIR__ . '/lib/all.php'; 25 | 26 | $qalist = QaFileInfo::cacheLoad(); 27 | 28 | foreach ( $qalist as $qafile ) 29 | { 30 | if ( $qafile->file == "bookinfo.xml" ) 31 | continue; 32 | if ( $qafile->sourceHash != $qafile->targetHash ) 33 | continue; 34 | 35 | $source = $qafile->sourceDir . '/' . $qafile->file; 36 | $target = $qafile->targetDir . '/' . $qafile->file; 37 | 38 | $s = XmlUtil::loadFile( $source ); 39 | $t = XmlUtil::loadFile( $target ); 40 | 41 | $s = XmlUtil::listNodeType( $s , XML_ELEMENT_NODE ); 42 | $t = XmlUtil::listNodeType( $t , XML_ELEMENT_NODE ); 43 | 44 | $s = extractTriple( $s ); 45 | $t = extractTriple( $t ); 46 | 47 | if ( implode( "\n" , $s ) == implode( "\n" , $t ) ) 48 | continue; 49 | 50 | $header = true; 51 | $match = []; 52 | 53 | foreach( $s as $v ) 54 | $match[$v] = array( 0 , 0 ); 55 | foreach( $t as $v ) 56 | $match[$v] = array( 0 , 0 ); 57 | 58 | foreach( $s as $v ) 59 | $match[$v][0] += 1; 60 | foreach( $t as $v ) 61 | $match[$v][1] += 1; 62 | 63 | foreach( $match as $k => $v ) 64 | { 65 | if ( $v[0] == $v[1] ) 66 | continue; 67 | 68 | if ( $header ) 69 | { 70 | print "qaxml.a: {$target}\n\n"; 71 | $header = false; 72 | } 73 | 74 | print "* {$k} -{$v[1]} +{$v[0]}\n"; 75 | } 76 | 77 | if ( ! $header ) 78 | print "\n"; 79 | } 80 | 81 | function extractTriple( array $list ) 82 | { 83 | $ret = []; 84 | foreach( $list as $elem ) 85 | foreach( $elem->attributes as $attrib ) 86 | $ret[] = "{$elem->nodeName} {$attrib->nodeName} {$attrib->nodeValue}"; 87 | return $ret; 88 | } 89 | -------------------------------------------------------------------------------- /docs/user-notes.md: -------------------------------------------------------------------------------- 1 | # User Note Editing Guidelines 2 | These are some guidelines to follow when editing user notes in the manual. 3 | 4 | To begin editing user notes in the manual, you must have a PHP.net account, and you must either: 5 | - Subscribe to the `php-notes` mailing list or newsgroup. As a user submits a new user note, it will appear 6 | as a message on the mailing list with links in the footer of the email that enable you to delete, edit, 7 | or reject that particular note. 8 | - Log on to the server at https://main.php.net/manage/user-notes.php using your PHP.net account username and password. 9 | The user notes administration interface enables you to search for user notes that match particular strings 10 | and edit or change the status of particular notes directly through the Web interface. 11 | 12 | The thing that seems to confuse the most people is the difference between *rejecting* and *deleting* a note. 13 | Basically, they both remove the note from the manual, but *rejecting* sends the user an email about the rejection 14 | with links to support links and other information. Here are some guidelines of when to use each. You can also view 15 | the exact text of the rejection email [here](https://github.com/php/web-master/blob/master/manage/user-notes.php). 16 | - If the note is asking for help (support request, *Does this work...?*, etc.) or if the person is reporting a bug, 17 | *reject* the note. The email will show them the proper place to report such issues. 18 | - If the note contains useful information appropriate for the manual proper, you may incorporate the information 19 | into the manual and then *delete* the note. 20 | - If the note is in the wrong place, incorrect, a giant block of silly, unnecessary code, poorly written, an answer 21 | to another person's question, or just overall confusing, *delete* it. If it was an answer to a question, hunt down 22 | that note and *reject* it. 23 | - If the note is in a language other than English, *delete* the note. 24 | - If the note submitter's email address is obviously bogus, don't *reject* the note, just *delete* it. 25 | Rejecting the note just gives the mail server more work trying to send an email to a non-existent address, 26 | which doesn't help anything. 27 | 28 | If for some reason you need to add to a note, first ask yourself if it's worth it. Make sure you're not answering 29 | a user's question; if you are, then the note doesn't belong there (see above). If you're clarifying a point, see 30 | if it is appropriate to add the clarification to the manual proper; if it is, add it and *delete* the note (see above). 31 | If you still feel that adding your addition to the note will be the best option, then go ahead and add it. Usually, editors 32 | add their note in a "Editor's Note" block at the top. Unless you are correcting a minor error, make it obvious that you edited the note. 33 | 34 | If you have some free time and commit access to phpdoc, try going through some of the manual pages and adding some of 35 | the better notes into the documentation proper. Be sure to *delete* these notes after they're implemented. 36 | 37 | If you are in doubt about what to do with a note, you may ask for help on the `php-notes` mailing list (or `phpdoc`, 38 | if what you're doing involves the documentation proper). 39 | -------------------------------------------------------------------------------- /scripts/translation/lib/XmlUtil.php: -------------------------------------------------------------------------------- 1 | | 15 | * +----------------------------------------------------------------------+ 16 | * | Description: Misc funcionality dealing with raw XML. | 17 | * +----------------------------------------------------------------------+ 18 | */ 19 | 20 | require_once __DIR__ . '/all.php'; 21 | 22 | class XmlUtil 23 | { 24 | public static function extractEntities( $filename ) 25 | { 26 | $was = libxml_use_internal_errors( true ); 27 | 28 | $doc = new DOMDocument(); 29 | $doc->recover = true; 30 | $doc->resolveExternals = false; 31 | $doc->load( $filename ); 32 | 33 | $errors = libxml_get_errors(); 34 | libxml_clear_errors(); 35 | libxml_use_internal_errors( $was ); 36 | 37 | $ret = []; 38 | foreach ($errors as $error) 39 | { 40 | if ( preg_match( "/Entity '(\S+)' not defined/" , $error->message , $matches ) ) 41 | $ret[] = $matches[1]; 42 | } 43 | return $ret; 44 | } 45 | 46 | public static function listNodeType( DOMNode $node , int $type ) 47 | { 48 | $ret = []; 49 | XmlUtil::listNodeTypeRecurse( $node , $type , $ret ); 50 | return $ret; 51 | } 52 | 53 | public static function listNodeTypeRecurse( DOMNode $node , int $type, array & $ret ) 54 | { 55 | if ( $node->nodeType == $type ) 56 | $ret[] = $node; 57 | foreach( $node->childNodes as $child ) 58 | XmlUtil::listNodeTypeRecurse( $child , $type, $ret ); 59 | } 60 | 61 | public static function loadFile( $filename ):DOMDocument 62 | { 63 | $contents = file_get_contents( $filename ); 64 | return XmlUtil::loadText( $contents ); 65 | } 66 | 67 | public static function loadText( $contents ):DOMDocument 68 | { 69 | $was = libxml_use_internal_errors( true ); 70 | 71 | $doc = new DOMDocument(); 72 | $doc->preserveWhiteSpace = true; 73 | $doc->recover = true; 74 | $doc->resolveExternals = false; 75 | $doc->substituteEntities = false; 76 | 77 | $doc->loadXML( $contents ); 78 | 79 | libxml_clear_errors(); 80 | libxml_use_internal_errors( $was ); 81 | 82 | return $doc; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /docs/editing.md: -------------------------------------------------------------------------------- 1 | # Editing manual sources 2 | 3 | Before making any changes to the manual - either the English version or a 4 | translation, make sure you have read the [style guidelines](style.md)! 5 | 6 | ## Editing existing documentation 7 | Simply open the files and edit them. 8 | 9 | ## Adding new documentation 10 | When adding new functions or methods, there are a few options: 11 | 12 | ### Option A: Generating stub using `gen_stub.php` 13 | This is the new preferred way to generate files for new extensions, classes, functions 14 | or methods using [`gen_stub.php`][gen_stub]. The script is found in the [php-src][php-src] 15 | repository and uses the stub files to generate documentation (DocBook) files. 16 | 17 | ### Option B: Generating files using docgen 18 | This is the old preferred way to generate files for new extensions, classes, functions 19 | or methods using [`docgen`][docgen]. The script is found in the [doc-base][doc-base] 20 | repository and uses reflection to generate documentation (DocBook) files. 21 | 22 | ### Option C: Copy skeleton files 23 | This involves copying the skeleton files into the correct location: 24 | ``` 25 | cp doc-base/skeletons/method.xml classname/methodname.xml #for new methods 26 | cp doc-base/skeletons/function.xml functions/functionname.xml #for new functions 27 | ``` 28 | 29 | Note: *classname*, *methodname* and *functionname* are lowercased names of the 30 | class, method, or function, respectively, not a literal file name. 31 | 32 | Remember the extension folder [structure](structure.md) when copying those files. 33 | 34 | ## Translating documentation 35 | The translation process is described in the [translating chapter](translating.md). 36 | 37 | Changes in the English version are eventually picked up by the translators. 38 | If a change doesn't affect translations (e.g. fixing a typo in English) then the 39 | commit message should start with `[skip-revcheck]`. 40 | 41 | ## Validating your changes 42 | Every time you make changes to documentation sources (both English or translation), 43 | you have to validate your changes to ensure that the manual still builds without error. 44 | The necessary [configure.php][configure.php] script is distributed with the 45 | [doc-base][doc-base] repository, so you should already have it. All you have 46 | to do to validate changes is run configure.php: 47 | ``` 48 | $ cd phpdoc 49 | $ php configure.php --with-lang={LANG} 50 | ``` 51 | If your language is English you can omit the `with-lang` argument. When the above 52 | outputs something like `"All good. Saving .manual.xml… done."` then you know it validates. 53 | You can commit your changes now. 54 | 55 | ## Commit changes 56 | If you have the appropriate access to the repository, you can commit your modified files. 57 | Otherwise, create a Pull Request to have your changes reviewed by the team. 58 | 59 | ## Viewing changes online 60 | The documentation used on the PHP.net website is rebuilt every few hours from 61 | the latest source pushed to the documentation trees. 62 | 63 | Read more details in [the appendix on public builds](public-builds.md). 64 | 65 | [docgen]: https://github.com/php/doc-base/tree/master/scripts/docgen 66 | [doc-base]: https://github.com/php/doc-base/ 67 | [gen_stub]: https://github.com/php/php-src/tree/master/build/gen_stub.php 68 | [php-src]: https://github.com/php/php-src/ 69 | [configure.php]: https://github.com/php/doc-base/blob/master/configure.php 70 | -------------------------------------------------------------------------------- /scripts/aspell.php: -------------------------------------------------------------------------------- 1 | #!/usr/bin/php 2 | | 16 | +----------------------------------------------------------------------+ 17 | */ 18 | 19 | /* 20 | See en.pws for list of ignored words. 21 | */ 22 | 23 | if ($_SERVER["argc"] != 3 || ($_SERVER["argv"][1] != "escape" && $_SERVER["argv"][1] != "unescape")) { 24 | exit("Purpose: Escape or unescape all *.xml files for use in aspell.\n" 25 | . "Usage: aspell.php escape|unescape \n" 26 | ); 27 | } 28 | 29 | // TODO: &xxx.xx; -> &xxx-xx; 30 | $GOOD_TAGS = "type|parameter|function|refname|literal|methodname|abbrev|acronym|constant|varname|replaceable|filename|userinput|command|structname|structfield"; 31 | $MODE = $_SERVER["argv"][1]; 32 | 33 | // htmlentities in comments and CDATA 34 | function callback_htmlentities($matches) { 35 | return $matches[1] . ($GLOBALS["MODE"] == "escape" ? htmlentities($matches[2]) : html_entity_decode($matches[2])) . $matches[3]; 36 | } 37 | 38 | // make attributes from contents of always-good tags 39 | function callback_make_value($matches) { 40 | return '<' . $matches[1] . $matches[2] . ' aspell="' . htmlentities($matches[3]) . '"/>'; 41 | } 42 | 43 | // make contents from attributes of always-good tags 44 | function callback_make_contents($matches) { 45 | return '<' . $matches[1] . $matches[2] . '>' . html_entity_decode($matches[3]) . ''; 46 | } 47 | 48 | function recurse($dir) { 49 | echo "$dir\n"; 50 | foreach (glob("$dir/*") as $filename) { 51 | if (is_dir($filename)) { 52 | recurse($filename); 53 | } elseif (preg_match('/\\.xml$/i', $filename)) { 54 | //~ echo "$filename\n"; 55 | $file = file_get_contents($filename); 56 | $file = preg_replace_callback('~()~sU', "callback_htmlentities", $file); 57 | $file = preg_replace_callback('~()~sU', "callback_htmlentities", $file); // isn't in one function as it can match !CDATA[[...--> 58 | if ($GLOBALS["MODE"] == "escape") { 59 | $file = preg_replace_callback('~<(' . $GLOBALS['GOOD_TAGS'] . ')( [^>]*)?>(.*)~sU', "callback_make_value", $file); 60 | } else { // "unescape" 61 | $file = str_replace("\r", "", $file); // for Windows version of Aspell 62 | $file = preg_replace_callback('~<(' . $GLOBALS['GOOD_TAGS'] . ')( [^>]*)? aspell="(.*)"/>~sU', "callback_make_contents", $file); 63 | } 64 | $fp = fopen($filename, "wb"); 65 | fwrite($fp, $file); 66 | fclose($fp); 67 | } 68 | } 69 | } 70 | 71 | recurse($_SERVER["argv"][2]); 72 | ?> 73 | -------------------------------------------------------------------------------- /scripts/translation/qaxml-entities.php: -------------------------------------------------------------------------------- 1 | | 14 | +----------------------------------------------------------------------+ 15 | 16 | # Description 17 | 18 | Compare XML entities usage between two XML leaf/fragment files. */ 19 | 20 | require_once __DIR__ . '/libqa/all.php'; 21 | 22 | $argv = new ArgvParser( $argv ); 23 | $ignore = new OutputIgnore( $argv ); // may exit. 24 | $urgent = $argv->consume( "--urgent" ) != null; 25 | 26 | $ents = []; 27 | foreach( $argv->residual() as $ent ) 28 | { 29 | if ( strlen( $ent ) > 2 && $ent[0] == '-' && $ent[1] != '-' ) 30 | { 31 | $ents[] = '&' . substr( $ent , 1) . ';'; 32 | $argv->use( $ent ); 33 | } 34 | } 35 | $argv->complete(); 36 | 37 | $list = SyncFileList::load(); 38 | 39 | foreach ( $list as $file ) 40 | { 41 | $source = $file->sourceDir . '/' . $file->file; 42 | $target = $file->targetDir . '/' . $file->file; 43 | $output = new OutputBuffer( "# qaxml.e" , $target , $ignore ); 44 | 45 | [ $_ , $s , $_ ] = XmlFrag::loadXmlFragmentFile( $source ); 46 | [ $_ , $t , $_ ] = XmlFrag::loadXmlFragmentFile( $target ); 47 | 48 | adornEntities( $s ); 49 | adornEntities( $t ); 50 | 51 | if ( implode( "\n" , $s ) == implode( "\n" , $t ) ) 52 | continue; 53 | 54 | $sideCount = []; 55 | 56 | foreach( $s as $v ) 57 | $sideCount[$v] = [ 0 , 0 ]; 58 | foreach( $t as $v ) 59 | $sideCount[$v] = [ 0 , 0 ]; 60 | 61 | foreach( $s as $v ) 62 | $sideCount[$v][0] += 1; 63 | foreach( $t as $v ) 64 | $sideCount[$v][1] += 1; 65 | 66 | foreach( $sideCount as $ent => $_ ) 67 | if ( in_array( $ent , $ents ) ) 68 | $sideCount[ $ent ] = [ 0 , 0 ]; 69 | 70 | foreach( $sideCount as $k => $v ) 71 | if ( $v[0] != $v[1] ) 72 | $output->addDiff( $k , $v[0] , $v[1] ); 73 | 74 | if ( $urgent ) 75 | { 76 | $count = 0; 77 | if ( $output->contains( "&chapters" ) ) 78 | $count++; 79 | if ( $output->contains( "&features" ) ) 80 | $count++; 81 | if ( $output->contains( "&language" ) ) 82 | $count++; 83 | if ( $output->contains( "&reference" ) ) 84 | $count++; 85 | if ( $output->contains( "&security" ) ) 86 | $count++; 87 | if ( $count == 0 ) 88 | continue; 89 | } 90 | 91 | $output->print(); 92 | } 93 | 94 | function adornEntities( array & $list ) 95 | { 96 | foreach( $list as & $item ) 97 | $item = '&' . $item . ';'; 98 | } -------------------------------------------------------------------------------- /skeletons/exceptionname.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | The ExceptionName class 4 | ExceptionName 5 | 6 | 7 | 8 | 9 |
10 | &reftitle.intro; 11 | 12 | Description of the exception. 13 | 14 |
15 | 16 | 17 |
18 | &reftitle.classsynopsis; 19 | 20 | 21 | 22 | 23 | ExceptionName 24 | 25 | 26 | 27 | 28 | extends 29 | BaseExceptionName 30 | 31 | 32 | 33 | &Methods; 34 | 35 | &Methods; 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 54 | &InheritedMethods; 55 | 56 | 57 | 58 | 59 |
60 | 61 |
62 | 63 | 66 | 67 |
68 | 88 | -------------------------------------------------------------------------------- /scripts/orphan_notes.php: -------------------------------------------------------------------------------- 1 | | 15 | +----------------------------------------------------------------------+ 16 | 17 | $Id$ 18 | */ 19 | 20 | /* 21 | * This script searches for orphan notes. 22 | * You need a phpweb checkout with, at least, 23 | * manual/en and backend/notes folders 24 | */ 25 | 26 | 27 | /* Configuration Options */ 28 | 29 | $manual_dir = 'manual/en'; 30 | $notes_dir = 'backend/notes'; 31 | 32 | /******* END of configurations *****/ 33 | 34 | 35 | /* Collect manual IDs */ 36 | function recurse_manual($dir) { 37 | global $array; 38 | 39 | if ($dh = opendir($dir)) { 40 | while (($file = readdir($dh)) !== false) { 41 | 42 | if($file != '.' && $file != '..') { 43 | $path = $dir.'/'.$file; 44 | 45 | if(is_dir($path)) { 46 | recurse_manual($path); 47 | } else { 48 | $array[substr(md5(substr($path, $GLOBALS['len'], -4)), 0, 16)] = 1; 49 | } 50 | 51 | } 52 | } 53 | closedir($dh); 54 | } 55 | } 56 | 57 | 58 | /* Search for bogus notes IDs */ 59 | function recurse_notes($dir) { 60 | global $array, $files, $notes; 61 | 62 | if ($dh = opendir($dir)) { 63 | while (($file = readdir($dh)) !== false) { 64 | 65 | if($file != '.' && $file != '..' && substr($file, -4) != '.bz2') { 66 | $path = $dir.'/'.$file; 67 | 68 | if(is_dir($path)) { 69 | recurse_notes($path); 70 | } else { 71 | if(!isset($array[$file]) && $file != 'last-updated' && $file != 'sections') { 72 | echo "file: $path\n"; 73 | 74 | $fp = fopen($path, "r"); 75 | while (!feof($fp)) { 76 | $line = chop(fgets($fp, 12288)); 77 | if ($line == "") { continue; } 78 | 79 | list($id, $sect, , , , ) = explode("|", $line); 80 | ++$notes; 81 | 82 | if (!isset($done)) { 83 | $done = 1; 84 | echo "old ID: $sect\nNotes IDs: $id"; 85 | 86 | } else { 87 | echo ", $id"; 88 | } 89 | } 90 | echo "\n\n"; 91 | ++$files; 92 | } 93 | 94 | unset($done); 95 | } 96 | } 97 | } 98 | closedir($dh); 99 | } 100 | } 101 | 102 | $array = array(); 103 | $len = strlen("$manual_dir/"); 104 | $files = $notes = 0; 105 | 106 | recurse_manual($manual_dir); 107 | recurse_notes($notes_dir); 108 | 109 | 110 | echo "\nTotal files: $files\nTotal notes: $notes"; 111 | ?> 112 | -------------------------------------------------------------------------------- /htmlhelp/local_vars.php.src: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /scripts/include/lib-translations.inc.php: -------------------------------------------------------------------------------- 1 | | 15 | | Some code stolen from other phpdoc/scripts/ | 16 | +----------------------------------------------------------------------+ 17 | 18 | $Id$ 19 | 20 | Introduction: 21 | 22 | This library is used by translation related scripts within 23 | the PHP Documentation repository. 24 | 25 | Usage examples: 26 | 27 | // Should this file be translated? 28 | if (!is_translatable ($filename)) { 29 | exit; 30 | } 31 | 32 | // Is the translation considered current? 33 | if (!is_translation_current ($file_en, $file_lang)) { 34 | exit; 35 | } 36 | 37 | */ 38 | 39 | function is_translation_current ($filename_en, $filename_lang) { 40 | 41 | if (!is_readable ($filename_en)) { 42 | trigger_error("File ($filename_en) is not readable", E_USER_WARNING); 43 | return false; 44 | } 45 | if (!is_readable ($filename_lang)) { 46 | trigger_error("File ($filename_lang) is not readable", E_USER_WARNING); 47 | return false; 48 | } 49 | 50 | $en = file_get_contents($filename_en); 51 | $lang = file_get_contents($filename_lang); 52 | 53 | $match_en = $match_lang = array(); 54 | 55 | preg_match ("//", $en, $match_en); 56 | preg_match ("/ 37 | 38 | 39 | 40 | 41 | 42 | 43 | &date.timezone.intro.title; 44 | &date.timezone.intro; 45 | 48 | 49 | 50 | 51 | &date.timezone.dbversion; . 52 | 53 | 54 | $zones) { 58 | $groupColumns = $columns; 59 | $m = count($zones) > ($groupColumns-1) ? $groupColumns : count($zones); ?> 60 | 61 | 62 | <?php echo '&date.timezone.' . strtolower($group) . ';'; ?> 63 | 64 | 65 | &date.timezone.bc; 66 | 67 | 68 | &date.timezone.posix-signs; 69 | 70 | 71 | 72 | <?php echo '&date.timezone.' . strtolower($group) . ';'; ?> 73 | 74 | 75 | ", PHP_EOL; 80 | } 81 | $c++; 82 | echo " {$zone}", PHP_EOL; 83 | if ($c % $m == 0) { 84 | echo " ", PHP_EOL; 85 | } 86 | } 87 | if ($c % $m != 0) { 88 | while($c++ % $m != 0) { 89 | echo " ", PHP_EOL; 90 | } 91 | echo " ", PHP_EOL; 92 | } 93 | ?> 94 | 95 | 96 |
97 |
98 | 99 |
100 | 101 | 121 | 122 | -------------------------------------------------------------------------------- /scripts/script-skel.php: -------------------------------------------------------------------------------- 1 | | 15 | +----------------------------------------------------------------------+ 16 | */ 17 | 18 | if (PHP_SAPI !== 'cli') { 19 | echo "This script is ment to be run under CLI\n"; 20 | exit(1); 21 | } 22 | 23 | if ($_SERVER['argc'] == 2 && 24 | in_array($_SERVER['argv'][1], array('--help', '-help', '-h', '-?')) 25 | || 26 | $_SERVER['argc'] < 2) { 27 | 28 | echo "\n\n"; 29 | echo "Usage: {$_SERVER['argv'][0]} \n"; 30 | echo " --help, -help, -h, -? - to get this help\n"; 31 | die; 32 | 33 | } 34 | 35 | // Ensure the trailing / 36 | $fullpath_dir = rtrim($_SERVER['argv'][1], '/').'/'; 37 | 38 | if (!is_dir($fullpath_dir)) { 39 | echo "ERROR: ($fullpath_dir) is not a directory.\n"; 40 | exit(1); 41 | } 42 | 43 | 44 | $log = array('nonfiles' => array(), 45 | 'error' => array(), 46 | 'rewritten' => array()); 47 | 48 | // Start the processing 49 | list_files($fullpath_dir, '', $log); 50 | 51 | 52 | 53 | echo count($log['rewritten'])." file(s) have been affected.\n"; 54 | if (!empty($log['error'])) { 55 | echo count($log['error'])." error(s) occured:\n"; 56 | foreach($log['error'] as $error) { 57 | echo " $error\n"; 58 | } 59 | } 60 | 61 | 62 | /** 63 | * List files recursivly and scan them 64 | * 65 | * @return bool 66 | */ 67 | function list_files($prefix, $path, &$userdata) 68 | { 69 | 70 | if (is_dir($prefix.$path) && is_resource($handle = @opendir($prefix.$path))) { 71 | 72 | while ($name = readdir($handle)) { 73 | if (strpos($name, ".xml") !== false) { 74 | scan_file($prefix, $path.$name, $userdata); 75 | } else if(is_dir($prefix.$path.$name) && $name !== 'CVS' && $name !== '.' && $name !== '..') { 76 | list_files($prefix, $path.$name.DIRECTORY_SEPARATOR, $userdata); 77 | } 78 | 79 | } 80 | 81 | closedir($handle); 82 | return true; 83 | 84 | } else { 85 | return false; 86 | } 87 | 88 | } 89 | 90 | /** 91 | * Scan files for examples, and insert them 92 | * 93 | * @return null 94 | */ 95 | function scan_file($prefix, $path, &$userdata) 96 | { 97 | 98 | if (!is_file($prefix.$path)) { 99 | $userdata['nonfiles'][] = $path; 100 | return false; 101 | } 102 | 103 | $content = file_get_contents($prefix.$path); 104 | echo "scanning $path\n"; 105 | if ($number = preg_match_all('/regex/', $content, $matches)) { 106 | 107 | // Process 108 | 109 | $userdata['rewritten'][] = $path; 110 | } 111 | 112 | } 113 | 114 | -------------------------------------------------------------------------------- /docs/structure.md: -------------------------------------------------------------------------------- 1 | # Documentation structure 2 | 3 | The PHP Manual sources are stored in Git repositories. 4 | 5 | To checkout the PHP Manual sources, follow the steps in [Setting up a documentation environment](local-setup.md) 6 | 7 | ## File structure 8 | 9 | **Note for translators:** if any of the source files don't exist in your translation, the English content will be used 10 | during the building process. This means that you *must not* place untranslated files in your translation tree. Otherwise, 11 | it will lead to a mess, confusion and may break some tools. 12 | 13 | The structure of the manual sources is hopefully rather intuitive. The most 14 | complicated part is the documentation for extensions, which is also the biggest 15 | part of the manual as all functions are grouped into extensions. 16 | 17 | The documentation for extensions is located in `reference/extension_name/`. For example, 18 | the calendar extension documentation exists in `reference/calendar/`. There you'll find several files: 19 | - *book.xml* - acts as the container for the extension and contains the preface. Other files (like examples.xml) 20 | are included from here. 21 | - *setup.xml* - includes setup, install and configuration documentation 22 | - *constants.xml* - lists all constants that the extension declares, if any 23 | - *configure.xml* - usually this information is in setup.xml, but if the file exists it is magically 24 | included into setup.xml 25 | - *examples.xml* - various examples 26 | - *versions.xml* - contains version information for the extension 27 | - *foo.xml* - example, foo can be anything specific to a topic. Just be sure to include via book.xml. 28 | 29 | A procedural extension (like calendar) also has: 30 | - *reference.xml* - container for the functions, rarely contains any info 31 | - *functions/* - folder with one XML file per function that the extension declares 32 | 33 | And OO extensions (such as imagick) contain: 34 | - *classname.xml* - container for the methods defined by the class, contains also basic info about it 35 | - *classname/* - folder with one XML file per method that the class declares 36 | 37 | Note: *classname* is the lowercased name of the class, not a literal file or directory name. 38 | 39 | There are some other important files: 40 | - *language-defs.ent* - contains local entities used by this language. Some common ones are 41 | the main part titles, but you should also put entities used only by this language's files here. 42 | - *language-snippets.ent* - longer often used XML snippets translated to this language. 43 | Including common warnings, notes, etc. 44 | - *translation.xml* - this file is used to store all central translation info, like a small 45 | intro text for translators and the persons list. This file is not present in the English tree. 46 | 47 | ## `xml:id` structure 48 | 49 | The PHP Manual is complex, and uses `xml:id`s extensively, for various 50 | purposes. So some care is necessary to avoid failures. 51 | There are two types of `xml:id`s used in manuals. 52 | 53 | * **Structural IDs:** IDs that are present on structural elements of 54 | DocBook XML (like ``, `
` and so on), that are used for 55 | linking and chunking; 56 | 57 | * **XInclude IDs:** IDs that are used as target of XIncludes. 58 | 59 | Structural IDs are in the pattern `id.id` (always one dot as separator), 60 | while XInclude IDs use the pattern `structural.id..local.name`. That is, 61 | for Structural IDs the name parts are separated with a *single* dot, while 62 | XInclude IDs are composed of an Structural ID prefix, a *double* dot separator, 63 | and a named suffix. 64 | 65 | The `configure.php` script will remove any duplicated IDs found. Without 66 | warnings in the case of XInclude IDs, so it is possible to use XInclude 67 | IDs elsewhere, and will warn about duplicate Structural IDs. 68 | -------------------------------------------------------------------------------- /scripts/fetch-chms.php: -------------------------------------------------------------------------------- 1 | $realfilename)\n"); 22 | 23 | $dlsize = fetch("$BUILDDIR/$filename", $tmpfilename); 24 | if (!$dlsize) { 25 | $err = error_get_last(); 26 | err($err["message"], $filename); 27 | continue; 28 | } 29 | debug("Fetched $dlsize"); 30 | 31 | $realhash = md5_file($tmpfilename); 32 | if ($realhash != $hash) { 33 | err("\nMD5 Failed for $filename ($realhash != $hash)\n"); 34 | continue; 35 | } 36 | debug("\nMD5 OK"); 37 | 38 | debug("Renaming $tmpfilename to $realfilename"); 39 | rename($tmpfilename, $realfilename); 40 | debug("All done with $filename"); 41 | } 42 | 43 | $errors = err(); 44 | if ($errors) { 45 | mail("phpdoc@lists.php.net", "Errors copying CHM files", var_export($errors, true), "From: phpdoc@lists.php.net\r\n", "-fnoreply@php.net"); 46 | return 2; 47 | } 48 | 49 | 50 | function err($error = null) { 51 | static $errors = array(); 52 | if ($error) { 53 | $errors[] = $error; 54 | } 55 | return $errors; 56 | } 57 | function debug($msg) { 58 | if (DEBUG) { 59 | echo $msg, "\n"; 60 | } 61 | } 62 | function stream_notification_callback($notification_code, $severity, $message, $message_code, $bytes_transferred, $bytes_max) { 63 | static $filesize = null; 64 | 65 | switch($notification_code) { 66 | case STREAM_NOTIFY_RESOLVE: 67 | case STREAM_NOTIFY_AUTH_REQUIRED: 68 | case STREAM_NOTIFY_COMPLETED: 69 | case STREAM_NOTIFY_FAILURE: 70 | case STREAM_NOTIFY_AUTH_RESULT: 71 | /* Ignore */ 72 | break; 73 | 74 | case STREAM_NOTIFY_REDIRECTED: 75 | debug("Being redirected to: ". $message); 76 | break; 77 | 78 | case STREAM_NOTIFY_CONNECT: 79 | debug("Connected..."); 80 | break; 81 | 82 | case STREAM_NOTIFY_FILE_SIZE_IS: 83 | $filesize = $bytes_max; 84 | debug("Filesize: ". $filesize); 85 | break; 86 | 87 | case STREAM_NOTIFY_MIME_TYPE_IS: 88 | debug("Mime-type: ". $message); 89 | break; 90 | 91 | case STREAM_NOTIFY_PROGRESS: 92 | if ($bytes_transferred > 0) { 93 | if (DEBUG) { 94 | if (!isset($filesize)) { 95 | printf("\rUnknown filesize.. %2d kb done..", $bytes_transferred/1024); 96 | } else { 97 | $length = (int)(($bytes_transferred/$filesize)*100); 98 | printf("\r[%-100s] %d%% (%2d/%2d kb)", str_repeat("=", $length). ">", $length, ($bytes_transferred/1024), $filesize/1024); 99 | } 100 | } 101 | } 102 | break; 103 | } 104 | } 105 | 106 | function fetch($filename, $outputname) { 107 | debug("Fetching $filename"); 108 | $ctx = stream_context_create(null, array("notification" => "stream_notification_callback")); 109 | 110 | $fp = fopen($filename, "r", false, $ctx); 111 | if (!is_resource($fp)) { 112 | err("Fetch failed"); 113 | return 0; 114 | } 115 | return file_put_contents($outputname, $fp); 116 | } 117 | 118 | 119 | 120 | -------------------------------------------------------------------------------- /scripts/translation/lib/RevcheckData.php: -------------------------------------------------------------------------------- 1 | | 15 | * +----------------------------------------------------------------------+ 16 | * | Description: DTO for serialization of revcheck data. | 17 | * +----------------------------------------------------------------------+ 18 | */ 19 | 20 | enum RevcheckStatus : string 21 | { 22 | case TranslatedOk = 'TranslatedOk'; 23 | case TranslatedOld = 'TranslatedOld'; 24 | case TranslatedWip = 'TranslatedWip'; 25 | case RevTagProblem = 'RevTagProblem'; 26 | case NotInEnTree = 'NotInEnTree'; 27 | case Untranslated = 'Untranslated'; 28 | } 29 | 30 | class RevcheckData 31 | { 32 | public string $lang = ""; 33 | public string $date = ""; 34 | public string $intro = ""; 35 | public $translators = []; // nick => RevcheckDataTranslator 36 | public $fileSummary = []; // RevcheckStatus => int 37 | public $fileDetail = []; // filename => RevcheckDataFile 38 | 39 | public function __construct() 40 | { 41 | foreach ( RevcheckStatus::cases() as $status ) 42 | $this->fileSummary[ $status->value ] = 0; 43 | } 44 | 45 | public function addFile( string $key , RevcheckDataFile $file ) 46 | { 47 | $this->fileDetail[ $key ] = $file; 48 | $this->fileSummary[ $file->status->value ]++; 49 | } 50 | 51 | public function getTranslator( string $nick ) 52 | { 53 | $translator = $this->translators[ $nick ] ?? null; 54 | if ( $translator == null ) 55 | { 56 | $translator = new RevcheckDataTranslator(); 57 | $translator->nick = $nick; 58 | $this->translators[ $nick ] = $translator; 59 | } 60 | return $translator; 61 | } 62 | 63 | public function getSummaryLabels() : array 64 | { 65 | $ret[ RevcheckStatus::TranslatedOk->value ] = "Up to date files"; 66 | $ret[ RevcheckStatus::TranslatedOld->value ] = "Outdated files"; 67 | $ret[ RevcheckStatus::TranslatedWip->value ] = "Work in progress"; 68 | $ret[ RevcheckStatus::RevTagProblem->value ] = "Revision tag missing/problem"; 69 | $ret[ RevcheckStatus::NotInEnTree->value ] = "Not in EN tree"; 70 | $ret[ RevcheckStatus::Untranslated->value ] = "Available for translation"; 71 | return $ret; 72 | } 73 | } 74 | 75 | class RevcheckDataTranslator 76 | { 77 | public string $name = ""; 78 | public string $email = ""; 79 | public string $nick = ""; 80 | public string $vcs = ""; 81 | 82 | public int $countOk = 0; 83 | public int $countOld = 0; 84 | public int $countOther = 0; 85 | } 86 | 87 | class RevcheckDataFile 88 | { 89 | public string $path; 90 | public string $name; 91 | public int $size; 92 | public int $days; 93 | public int $adds = 0; 94 | public int $dels = 0; 95 | 96 | public RevcheckStatus $status; 97 | public string $maintainer = ""; 98 | public string $completion = ""; 99 | 100 | public string $hashLast; // The most recent commit hash, skipped or not 101 | public string $hashDiff; // The most recent, non [skip-revcheck] commit hash 102 | public string $hashRvtg = ""; // Revtag hash, if any 103 | } 104 | --------------------------------------------------------------------------------