phpMyFAQ - Open Source FAQ web application for PHP and MySQL, PostgreSQL and other databases

Overview

phpMyFAQ 3.1

Packagist PHP Version Support GitHub GitHub commit activity

What is phpMyFAQ?

phpMyFAQ is a multilingual, completely database-driven FAQ-system. It supports various databases to store all data, PHP 7.3+ is needed in order to access this data. phpMyFAQ also offers a multi-language Content Management System with a WYSIWYG editor and a media manager, real time search support with Elasticsearch, flexible multi-user support with user and group based permissions on categories and records, a wiki-like revision feature, a news system, user-tracking, 40+ supported languages, enhanced automatic content negotiation, HTML5/CSS3 based responsive templates, PDF-support, a backup and restore system, a dynamic sitemap, related FAQs, tagging, enhanced SEO features, built-in spam protection systems, OpenLDAP and Microsoft Active Directory support, and an easy-to-use installation and update script.

Requirements

phpMyFAQ is only supported on PHP 7.3 and up, you need a database as well. Supported databases are MySQL, MariaDB, Percona Server, PostgreSQL, Microsoft SQL Server and SQLite3. If you want to use Elasticsearch as main search engine, you need Elasticsearch 5.x or later. Check our detailed requirements on phpmyfaq.de for more information.

Installation

phpMyFAQ installation package for end-users

The best way to install phpMyFAQ is to download it on phpmyfaq.de, unzip the package and open http://www.example.org/phpmyfaq/setup/index.php in your preferred browser.

phpMyFAQ installation with Docker

Dockerfile

The Dockerfile provided in this repo only build an environment to run any release it's for development purpose. It does not contain any code as the phpmyfaq folder is meant to be mounted as the /var/www/html folder in the container.

To build a production release please use the docker-hub repository or use images provided on docker.io.

docker-compose.yml

For development purposes you can start a full stack to run your current PhpMyFAQ source code from your local repo.

$ docker-compose up

The command above starts 8 containers for multi database development as following.

Specific images started once to prepare the project:

  • composer: update composer dependencies
  • yarn: update yarn dependencies

Running using named volumes:

  • mariadb: image with MariaDB database with xtrabackup support
  • phpmyadmin: a PHP tool to have a look on your MariaDB database.
  • postgres: image with PostgreSQL database
  • pgadmin: a PHP tool to have a look on your PostgreSQL database.
  • sqlserver: image with Microsoft SQL Server for Linux
  • elasticsearch: Open Source Software image (it means it does not have XPack installed)

Running apache web server with PHP 8.0 support:

  • phpmyfaq: mounts the phpmyfaq folder in place of /var/www/html.

Then services will be available at following addresses:

Running tests

To run the test using Docker you have to install the Composer development dependencies

$ curl -s https://getcomposer.org/installer | php
$ php composer.phar install

Quote from ElasticSearch documentation

The vm.max_map_count kernel setting needs to be set to at least 262144 for production use. Depending on your platform:

Linux

The vm.max*map_count setting should be set permanently in */etc/sysctl.conf_:

$ grep vm.max_map_count /etc/sysctl.conf
vm.max_map_count=262144

To apply the setting on a live system type: sysctl -w vm.max_map_count=262144

macOS with Docker for Mac

The vm.max_map_count setting must be set within the xhyve virtual machine:

$ screen ~/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux/tty

Log in with root and no password. Then configure the sysctl setting as you would for Linux:

$ sysctl -w vm.max_map_count=262144
Windows and macOS with Docker Toolbox

The vm.max_map_count setting must be set via docker-machine:

$ docker-machine ssh
$ sudo sysctl -w vm.max_map_count=262144

phpMyFAQ local installation from Github

To run phpMyFAQ locally you need at least a running web server with PHP support and a database.

$ git clone git://github.com/thorsten/phpMyFAQ.git
$ cd phpMyFAQ
$ curl -s https://getcomposer.org/installer | php
$ php composer.phar install
$ curl -o- -L https://yarnpkg.com/install.sh | bash
$ yarn install
$ yarn build

Then just open http://www.example.org/phpmyfaq/setup/index.php in your browser.

Testing

To run our unit tests via PHPUnit v9.x, just execute this command on your CLI

$ curl -s https://getcomposer.org/installer | php
$ php composer.phar install
$ ./vendor/bin/phpunit

Please note that phpMyFAQ needs to be installed via Composer.

Versioning

For transparency and insight into our release cycle, and for striving to maintain backward compatibility, phpMyFAQ will be maintained under the Semantic Versioning guidelines as much as possible.

Releases will be numbered with the following format:

<major>.<minor>.<patch>

And constructed with the following guidelines:

  • Breaking backward compatibility bumps the major (and resets the minor and patch)
  • New additions without breaking backward compatibility bumps the minor (and resets the patch)
  • Bug fixes and misc changes bumps the patch

For more information on SemVer, please visit http://semver.org/.

Bug tracker

Found a bug, or do you have a feature request? Please open a new issue. Before opening any issue, please search for existing issues.

Contributing

Please check out our page about contributing on phpmyfaq.de.

Documentation

You can find the full documentation on phpmyfaq.de.

REST API v2

The REST API v2 documentation is located here in this repository and on phpmyfaq.de.

License

Mozilla Public License 2.0, see LICENSE for more information.

Copyright © 2001 - 2021 Thorsten Rinne and the phpMyFAQ Team

Comments
  • Feature request: Mermaid (Markdown)

    Feature request: Mermaid (Markdown)

    Mermaid - with the fantastic move to MarkDown, I'd love to see this utility incorporated. I haven't seen mention of it anywhere so I'm adding it here. https://github.com/knsv/mermaid It is SO convenient especially in a FAQ system

    New feature 
    opened by mtompkins 49
  • Session timeout despite

    Session timeout despite "remember me" selected by login

    Greetings,

    i mentioned the problem already: https://github.com/thorsten/phpMyFAQ/issues/948

    My current version is PHPmyFAQ Version: 2.8.22

    Despite i allready logged in (with password remember me) and i can use the frontend, following is not possible after uncertain time.

    • quick search \ schnellsuche doesnt work after a while but the normal search works..
    • search for internal links
    • sometimes it`s necessary to Login again to create a new FAQ but the full secured frontend works without a new login
    • Upload from new files (attachments or Pictures) requires to login again. (but you have to logout from phpmyfaq and Login again)

    The cookie seems not work for the admin panel \ Editor correctly.

    My constants.php (24h timeout) [code] /**

    • Timeout for the admin section, in minutes *
    • @var integer */ define('PMF_AUTH_TIMEOUT', 1440);

    // Misc parameters define('PMF_LANGUAGE_EXPIRED_TIME', 28800); // 30 minutes define('PMF_SESSION_EXPIRED_TIME', 28800); // 30 minutes define('PMF_REMEMBERME_EXPIRED_TIME', 1209600); // 2 weeks

    [/code]

    My php-settings concerning Sessions. http://2moons.zapto.org/phpinfo-session.jpg

    I use Internet Explorer 11 and have emptied the complete cache and so on, but same behavior.

    Bug 
    opened by robin-masters 41
  • 2.7 RC Fix Search

    2.7 RC Fix Search

    I just discovered today while having a user search for something in my FAQ that i am not sure if possible to fix or not but would be great if it could.....

    for example they searched for this

    I bought a Magic Jack Plus i'd like to use without

    and it acually shows up like this

    i bought magic plus i&# 39;d like to use without

    it adds the ' if you use an apostrophe inbetween the I'D

    Thats how it showed up in database so thats why i thought theres no way to fix that, on the front end it appears ok but

    but if you remember the other problem i was having after time and my site being indexed this other one started appearing in my phpmyadmin database and frontend NOT YET%2C BUT COMING SOON! We are working

    and would like to prevent that from happening to search terms that use any symbols

    Bug 
    opened by jason102178 39
  •  Can I remove the “&cat=.*” from the URL?

    Can I remove the “&cat=.*” from the URL?

    Phpmyfaq is a simple and powerful software, I like it very much.

    Can I remove the “&cat=.*” from the URL?

    Get a url like this: index.php?action=artikel&id=1&artlang=en

    Because only ID is unique in URL.

    Thank you very much.

    Bug 
    opened by yaoguangxiao 30
  • Configuration doesn't save

    Configuration doesn't save

    Any changes I make in the configuration revert to defaults after hitting Save. There was only one instance when changes did save but I have no idea why. I changed files permissions to 755 except for the four folders mentioned in docs which I changed to 775. I also tried different browser with and without private modes.

    Bug 
    opened by rutra80 30
  • 2.7 RC export pdf

    2.7 RC export pdf

    I know the exporting pdf and exporting pdf inline both worked before but i dont know if you can reproduce this or are having this issue, i tested in both firefox and internet explorer..

    when i click export pdf all it does is open in a new tab and the page is blank instead of acually letting you download or see the odf of your FAQ

    I thought maybe logging out and re logging in might help but it didnt

    update: another area with a pdf issue is on the front end when you click on a category then a topic and on right colum click on pdf button the same thing happens a blank page and nothing happens

    i also test this on my localhost machine and does same thing

    Bug 
    opened by jason102178 29
  • Installation causes external requests

    Installation causes external requests

    It seems some component of phpMyFAQ is causing an external request from 81.246.43.103. In short, my use of phpMyFAQ is purely internal and I have safeguards in place to ensure that is the case. There should be no 'announcement' or other information from the internal network disclosed to external entities. There should be no reason for an external to be requesting anything within my DMZ zone.

    I find that after installing phpMyFAQ, requests are made to apache host from the above identified IP address, which resolves to the following information: http://www.networksolutions.com/whois/results.jsp?ip=81.246.43.103

    There is no DNS registration or other CNAME publicly registered for the virtual server I am using. This condition has been replicated on an independent network with the same results.

    I find this quite troubling. Luckily I control access at the global level of apache which is preventing this access.

    Here is the apache log:

    [Fri Nov 27 11:09:39.111335 2015] [access_compat:error] [pid 1839] [client 81.246.43.103:53407] AH01797: client denied by server configuration: /var/www/faq/ [Fri Nov 27 11:09:39.112665 2015] [access_compat:error] [pid 1839] [client 81.246.43.103:53407] AH01797: client denied by server configuration: /var/www/custom-errors/401error.html

    Here is the associated access attempt: 81.246.43.103 - - [27/Nov/2015:11:09:39 -0500] "GET / HTTP/1.1" 401 28705 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"

    Bug 
    opened by mtompkins 25
  • 2.7 RC: In category listing all Main categories appears as child of first main category

    2.7 RC: In category listing all Main categories appears as child of first main category

    Only the first cat is displayed. Footer is before "Attachment" item. I'll send to [email protected] a screenshot.

    Can be seen at http://fdfaq.ge51.honeywell.de

    Bug 
    opened by JochenS 25
  • Elastic search - how to test

    Elastic search - how to test

    Describe the bug I have created index in elastic search configuration page. When I search with less than 4 characters, it returns data. For letters more than 4 character, I am getting error.

    To Reproduce Steps to reproduce the behavior:

    1. Go to elastic search configuration on Admin side and click Create Index,
    2. Go to Search page on front-end
    3. Search for string less than and greater than 4 characters
    4. Enable debug mode and see error

    Expected behavior Search should happen without errors.

    Screenshots image

    phpMyFAQ (please complete the following information):

    • phpMyFAQ version - 3.0.5
    • PHP version - 7
    • Database - mySQL
    • Elasticsearch yes/no - Yes 7.9.2

    Additional context I am not sure how to know if my search is working through elastic search or full-text.

    Bug 
    opened by ushah001 23
  • SMTP SSL/TLS and non standard ports

    SMTP SSL/TLS and non standard ports

    From what I understand neither SSL/TLS nor configurable ports are supported as of 3.0.0B2. Our host demands it. Is there A a workaround (ie changing the script locally with hard coded values) and B a feature request on this (last post on the forum was from early 2017 :-)

    /Henrik

    Improvement 
    opened by werkstrom 23
  • Unable to view new FAQ on front end - v2.9.0-alpha3

    Unable to view new FAQ on front end - v2.9.0-alpha3

    Spun up a new install - default settings (basic, no groups). Entered a new FAQ in the backend, entered as MD using editor. Checked preview - looked good (change to highlighter seems to have resolved the apostraphe issue)

    Tried to view the FAQ in front end, no HTML returned...no errors shown in apache. Sounds like possible additional authorization bugs at a guess. Should be easy enough to reproduce.

    Bug Needs feedback 
    opened by mtompkins 23
  • api category testing

    api category testing

    Using: [phpMyFAQ 3.2.0-alpha].

    Just trying out your changes - Thanks Thorsten

    Trying to add a root category using api (currently no categories exist in the database). Curl Commands : 1.) curl --location --request POST 'http://devbox.local:85/phpmyfaq/api/v2.2/category' --header 'X-PMF-Token: 850b5c2c-d478-4261-b43a-b658bb0257c2' --header 'Accept-Language: fr' --header 'Content-Type: application/json' -d '{"language": "fr", "parent-id": "", "category-name": "fred", "description": "", "user-id": "1", "group-id": "", "is-active": "true", "show-on-homepage": "false"}' 2.) curl --location --request POST 'http://devbox.local:85/phpmyfaq/api/v2.2/category' --header 'X-PMF-Token: 850b5c2c-d478-4261-b43a-b658bb0257c2' --header 'Accept-Language: fr' --header 'Content-Type: application/json' -d '{"language": "fr", "parent-id": "0", "category-name": "fred", "description": "", "user-id": "1", "group-id": "", "is-active": "true", "show-on-homepage": "false"}' 3.) curl --location --request POST 'http://devbox.local:85/phpmyfaq/api/v2.2/category' --header 'X-PMF-Token: 850b5c2c-d478-4261-b43a-b658bb0257c2' --header 'Accept-Language: fr' --header 'Content-Type: application/json' -d '{"language": "fr", "parent-id": "0", "parent-category-name": "", "category-name": "fred", "description": "", "user-id": "1", "group-id": "", "is-active": "true", "show-on-homepage": "false"}'

    Response to command line output for 1.) and 2.)

    phpMyFAQ Fatal error

    Uncaught exception: 'ErrorException'

    Message: 'Undefined array key "parent-category-name"'

    Stack trace:

    #0 /var/www/html/phpmyfaq/api.php(223): phpMyFAQ\Core\Error::errorHandler()
    #1 {main}

    Thrown in '/var/www/html/phpmyfaq/api.php' on line 223

    And for 3.) {"stored":false,"error":"The given parent category name was not found."}

    I guess fair enough for 3.)

    Question A.) So how do I add a root category when no other category exists ?

    B.) Also "idiot question" In the "dev" administration, how do I manually create categories. The dev interface is different to the previous one I used from release on 3.1.9 and when I click Categories->Add New - nothing seems to happen on the "dev" screen"

    I'll try to create a single category and continue with the api.

    C.)The Category api payload demands: "user-id": "[user id as integer value, required value]", "group-id": "[group-id as integer value, required value]", Which is different to add faq, where call expects an email address not a user-id.

    This means the user needs to know implementation details - not a big problem but just wondered about that.

    Bug API 
    opened by mark-Wh 7
  • api post faq - The json payload has

    api post faq - The json payload has "is-active": "true" but the created faq has active=0 in database

    Following on from defect 2276......sorry

    phpMyFAQ (please complete the following information):

    phpMyFAQ = 3.1.9 (2022-12-11) PHP version = PHP 8.1.13 Database = mysql 8 Elasticsearch = NO using php docker apache container (php:8.1-apache)

    Using example curl command to create faq : curl --location --request POST 'http://devbox.local:85/phpmyfaq/api/v2.1/faq' --header 'X-PMF-Token: 850b5c2c-d478-4261-b43a-b658bb0257c2' --header 'Accept-Language: fr' --header 'Content-Type: application/json' -d '{"language": "fr","category-id": "3", "question": "Codes erreur et messages / Balboa / M7 / SnS, Sn", "answer": "Capteurs déséquilibrés", "keywords": "Codes erreur et messages, Balboa, M7", "author": "[email protected]", "email": "[email protected]", "is-active": "true", "is-sticky": "false"}'

    The json has "is-active": "true"

    But when created in the database, the newly created faq entry in the 'faqdata' table has column active = 0.

    This means when bulk creating faq, you must manually update each record to set the FAQ status to "published".

    Bug API 
    opened by mark-Wh 3
  • api post faq - FaqEntity::setLanguage(): Argument #1 ($language) must be of type string

    api post faq - FaqEntity::setLanguage(): Argument #1 ($language) must be of type string

    executed following curl command to add an faq using webservice curl -v -H "Accept-Language: fr" -H "X-PMF-Token: 850b5c2c-d478-4261-b43a-b658bb0257c2" -d '{"language": "fr","category-id": "4", "question": "my first api post?", "answer": "fred", "keywords": "frank", "author": "[email protected]", "email": "[email protected]", "is-active": "true", "is-sticky": "false"}' 'http://devbox.local:85/phpmyfaq/api.php?action=faq'

    apache log output following: [Wed Dec 28 15:54:18.989520 2022] [php:notice] [pid 39] [client 192.168.1.39:52350] phpMyFAQ TypeError: phpMyFAQ\Entity\FaqEntity::setLanguage(): Argument #1 ($language) must be of type string, null given, called in /var/www/html/phpmyfaq/api.php on line 351 in /var/www/html/phpmyfaq/src/phpMyFAQ/Entity/FaqEntity.php on line 115\nStack trace:\n#0 /var/www/html/phpmyfaq/api.php(351): phpMyFAQ\Entity\FaqEntity->setLanguage()\n#1 {main} 192.168.1.39 - - [28/Dec/2022:15:54:18 +0000] "POST /phpmyfaq/api.php?action=faq HTTP/1.1" 500 499 "-" "curl/7.68.0"

    And faq was not added.

    I can successfully use web interface to create faq

    NOTE: I tried following get request which correctly returned a json response: curl -H "Accept-Language: fr" 'http://devbox.local:85/phpmyfaq/api.php?action=search&q=m7'

    This is my first time using phpMyFAQ (and a php application) so apologies if there is something obvious I need to check.

    phpMyFAQ (please complete the following information):

    • phpMyFAQ = 3.1.9 (2022-12-11)
    • PHP version = PHP 8.1.13
    • Database = mysql 8
    • Elasticsearch = NO using php docker apache container (php:8.1-apache)
    Bug API 
    opened by mark-Wh 9
  • SSO not enable or How to enable SSO

    SSO not enable or How to enable SSO

    I have existing code on Larval thats we use casauth for SSO. Now I am going to add FAQ feature. SSO documentation not available. I am enabled SSO on configuration but its working for logout. Kindly let me know the steps to SSO enable. Because sso login we have how to integrate with phpmyfaq site.

    Improvement 
    opened by gowthamanmuthu 11
  • Faq content is truncated for category API

    Faq content is truncated for category API

    Is your feature request related to a problem? Please describe. API (/api/v2.1/faqs/:categoryId) only provides record_preview, i.e truncated faq content. In order to have the full faq content, the app needs to request another query to get the full FAQ data.

    Describe the solution you'd like It would be great to have faq content to be displayed fully for API (/api/v2.1/faqs/:categoryId) query. The manipulation of data should be left for the code that request the API query.

    Describe alternatives you've considered Maybe have another parameter in getAllRecordsByCategoryId() to toggle whether it's for preview purposes or full data query.

    New feature 
    opened by fbunadi 1
Independent query builders for MySQL, PostgreSQL, SQLite, and Microsoft SQL Server.

Aura.SqlQuery Provides query builders for MySQL, Postgres, SQLite, and Microsoft SQL Server. These builders are independent of any particular database

Aura for PHP 424 Dec 12, 2022
PHP Object Model Manager for Postgresql

POMM: The PHP Object Model Manager for Postgresql Note This is the 1,x version of Pomm. This package is not maintained anymore, the stable Pomm 2.0 is

Grégoire HUBERT 161 Oct 17, 2022
A simple library to access and manipulate database records. Built on top of Dibi and hardwired for PostgreSQL.

grifart/tables A simple library to access and manipulate database records. Built on top of Dibi and hardwired for PostgreSQL. This library is develope

GRIFART 5 Nov 11, 2022
🔌 A Doctrine DBAL Driver implementation on top of Swoole Coroutine PostgreSQL extension

Swoole Coroutine PostgreSQL Doctrine DBAL Driver A Doctrine\DBAL\Driver implementation on top of Swoole\Coroutine\PostgreSQL. Getting started Install

Leo Cavalcante 19 Nov 25, 2022
Support for many missing PostgreSQL specific features

Laravel supports many different databases and therefore has to limit itself to the lowest common denominator of all databases. PostgreSQL, however, of

Tobias Petry 359 Jan 3, 2023
Laravel Thermite is an extended PostgreSQL Laravel database driver to connect to a CockroachDB cluster.

Laravel Thermite Laravel Thermite is an extended PostgreSQL Laravel database driver to connect to a CockroachDB cluster. ?? Supporting If you are usin

Renoki Co. 9 Nov 15, 2022
PostgreSQL enhancements for Doctrine

PostgreSQL enhancements for Doctrine. Provides support for advanced data types (json, jssnb, arrays), text search, array operators and jsonb specific functions.

Martin Georgiev 258 Dec 31, 2022
Orm is a simple database abstraction layer that supports postgresql.

Orm What is it Orm is a simple database abstraction layer that supports postgresql. Welcome to join us or star us for encouragement. Requires php 8.1

null 2 Sep 28, 2022
This package provides a framework-agnostic database backup manager for dumping to and restoring databases from S3, Dropbox, FTP, SFTP, and Rackspace Cloud

Database Backup Manager This package provides a framework-agnostic database backup manager for dumping to and restoring databases from S3, Dropbox, FT

Backup Manager 1.6k Dec 23, 2022
ATK Data - Data Access Framework for high-latency databases (Cloud SQL/NoSQL).

ATK Data - Data Model Abstraction for Agile Toolkit Agile Toolkit is a Low Code framework written in PHP. Agile UI implement server side rendering eng

Agile Toolkit 257 Dec 29, 2022
You can sync any number of PDO supported databases

Features: Can backup any number of databases. No need to introduce column name only table name The Last id based data backup Support 12 different data

Tharusha Kavishan Udumulla 4 Aug 27, 2021
Small script for importing the KvK (Dutch Chamber of Commerce) Open Data Set (CSV file) to a MySQL database.

KvK-CSV-2-SQL Small script for importing the KvK (Dutch Chamber of Commerce) Open Data Set (CSV file) to a MySQL database. Table of content KvK-CSV-2-

BASTIAAN 3 Aug 5, 2022
Propel2 is an open-source high-performance Object-Relational Mapping (ORM) for modern PHP

Propel2 Propel2 is an open-source Object-Relational Mapping (ORM) for PHP. Requirements Propel uses the following Symfony Components: Config Console F

Propel 1.2k Dec 27, 2022
Staggered import of large and very large MySQL Dumps even through the web servers with hard runtime limit and those in safe mode.

Staggered import of large and very large MySQL Dumps (like phpMyAdmin dumps) even through the web servers with hard runtime limit and those in safe mode. | Persian Translation Version

Amir Shokri 5 Jan 8, 2022
A web interface for MySQL and MariaDB

phpMyAdmin A web interface for MySQL and MariaDB. https://www.phpmyadmin.net/ Code status Download You can get the newest release at https://www.phpmy

phpMyAdmin 6.4k Jan 5, 2023
TO DO LIST WITH LOGIN AND SIGN UP and LOGOUT using PHP and MySQL please do edit the _dbconnect.php before viewing the website.

TO-DO-LIST-WITH-LOGIN-AND-SIGN-UP TO DO LIST WITH LOGIN AND SIGN UP and LOGOUT using PHP and MySQL please do edit the _dbconnect.php before viewing th

Aniket Singh 2 Sep 28, 2021
A simple and extensible fixture loader for PHP 7.3+, supporting SQLite and MySQL

Flowder Flowder is a (really) simple fixture loader for PHP 7.3+, supporting SQLite and MySQL. Using Flowder in PHP 7.2 or below? Try version 1 instea

Joe Haines 6 Jan 17, 2021
Connect and work with MySQL/MariaDB database through MySQLi in PHP. This is an introductory project, If you need a simple and straightforward example that takes you straight to the point, you can check out these examples.

First MySQLi PHP Connect and work with MySQL/MariaDB database through MySQLi in PHP. The above exercises are designed for students. This is an introdu

Max Base 4 Feb 22, 2022
A simple PHP and MySQL based internet forum that displays the messages in classical threaded view (tree structure)

my little forum my little forum is a simple PHP and MySQL based internet forum that displays the messages in classical threaded view (tree structure).

Mark Hoschek 97 Dec 29, 2022