...
 
Commits (89)
/.idea/
/.web-server-pid
/app/config/parameters.yml
......
File mode changed from 100644 to 100755
......@@ -10,7 +10,10 @@ RUN apk update \
python-dev \
py-pip
RUN pip install mkdocs mkdocs-material pygments pymdown-extensions
RUN pip install 'mkdocs==0.16.1'
RUN pip install 'mkdocs-material==1.4.1'
RUN pip install 'pygments==2.2.0'
RUN pip install 'pymdown-extensions==2.0'
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
......
......@@ -6,44 +6,12 @@ You may also wish to:
- [*Read* these documentation books](https://civicrm.org/documentation) *(and other sources of documentation)*
- [*Contribute* to documentation content](https://docs.civicrm.org/dev/en/master/documentation/)
- [*Add* a new documentation book](https://lab.civicrm.org/documentation/docs-books)
## Documentation books
## Defining new books
CiviCRM documentation is organised into various *books*. The content for a book is written in [markdown](https://docs.civicrm.org/dev/en/master/markdownrules/) and stored in a git repository (for example https://github.com/civicrm/civicrm-user-guide ). If a book is translated into different languages, then a separate repository is used for each language. If required, different *versions* of a book can be made by creating different *branches* in a repository. See *Defining books* below for more information.
## Defining a new book
Books are defined with a Yaml configuration file. To define a new book, create a `.yml` file and add it to the `app/config/books/` directory of this repository.
The config file defines the name of the book, the repository that contains the source code, and the **languages** that the book is available in, with a repository for each language. For each language, the configuration file defines:
* which **edition** of the book should be considered **stable**
* where to find the **latest** edits to the book
* a history of book **editions** of the book (these will be publicly listed at https://docs.civicrm.org/).
If you would like to be notified by email whenever an update to a book is published, you can add your email to the notify list.
**Example book definition:**
```yml
name: User guide
description: Aimed at day to day users of CiviCRM.
langs:
en:
repo: 'https://github.com/michaelmcandrew/civicrm-user-guide'
latest: master
stable: 4.7
history:
- 4.6
- 4.5
- 4.4
notify:
michael@civicrm.org # will be notified when documentation is published (as well as any emails mentioned in commits)
ca:
repo: 'https://github.com/babu-cat/civicrm-user-guide-ca'
latest: master
# stable: master (will not be published)
```
This information/content has moved to a new repository. Click here to see the [docs-books repository](https://lab.civicrm.org/documentation/docs-books).
## Publishing updates to a book
......@@ -51,12 +19,20 @@ Books are automatically published when the corresponding branch is updated their
### Setting up automatic publishing
#### GitHub
Auto updates are configured via webhooks within the repository on GitHub. You will need to be an owner (not just a collaborator) of the repository in order to perform these steps.
1. Go to `https://github.com/civicrm/[repo-name]/settings/hooks/new`
1. Set the **Payload URL** to https://docs.civicrm.org/admin/listen
1. Set the **Content type** to 'application/json'
1. Set **Which events would you like to trigger this webhook?** to 'Let me select individual events' and select 'Pull request' and 'Push' (since these are the only events that should trigger an update)
1. Go to `https://github.com/[user-or-group-name]/[repo-name]/settings/hooks/new`
2. Set the **Payload URL** to `https://docs.civicrm.org/admin/listen`
3. Set the **Content type** to 'application/json'
4. Set **Which events would you like to trigger this webhook?** to 'Let me select individual events' and select 'Pull request' and 'Push' (since these are the only events that should trigger an update)
#### GitLab
1. Go to `https://lab.civicrm.org/[user-or-group-name]/[repo-name]/settings/integrations`
2. Set the **URL** to `https://docs.civicrm.org/admin/listen`
3. Set the **Trigger** to 'Push events' and 'Tag push events'.
### Manual publishing
......@@ -67,8 +43,8 @@ https://docs.civicrm.org/admin/publish/{book}/{lang}/{branch}
```
* `{book}` the name of the book - as per configuration file in the conf/books directory.
* `{lang}` the language that you want to publish - as defined in the configuration file.
* `{branch}` the name of the branch that you want to publish - needs to be a branch in the repository for that language.
* `{lang}` the language that you want to publish - as defined in the configuration file **(Optional)**.
* `{branch}` the name of the branch that you want to publish - needs to be a branch in the repository for that language **(Optional)**.
## Installing a local copy of the docs infrastructure
......@@ -104,26 +80,78 @@ You should be able to see the app at http://localhost:8080.
**Note**: the following steps are only useful and necessary for people looking after CiviCRM's documentation *infrastructure*. You don't need to do this if you just want to [contribute to documentation content](https://docs.civicrm.org/dev/en/master/documentation/).
1. Ensure that that you have [pip](https://packaging.python.org/en/latest/install_requirements_linux/#installing-pip-setuptools-wheel-with-linux-package-managers) (for python) and [composer](https://getcomposer.org/) (for php) installed..
2. [Install MkDocs](https://docs.civicrm.org/dev/en/master/documentation/#mkdocs). Ensure that MkDocs is installed as root so that it can be accessed from the src/publish.php script (typically invoked as https://docs.civicrm.org/publish.php)*
3. clone this repository to somewhere like /var/www/civicrm-docs and run `composer install`
```bash
$ git clone /var/www/civicrm-docs
$ cd /var/www/civicrm-docs
$ composer install
```
4. Set appropriate permissions on web/static
5. Configure an nginx virtual host
```bash
$ cd /etc/nginx/sites-enabled
$ ln -s /var/www/civicrm-docs/app/config/nginx.conf civicrm-docs
```
1. Install the pre-requisites:
**Note**: the example commands have been tested on Ubuntu 16.04 and 18.04.
* [nginx](https://nginx.org):
``` bash
sudo apt install nginx
```
* [mysql](https://mysql.com):
``` bash
sudo apt install mysql-server
```
* [curl](https://curl.haxx.se/):
``` bash
sudo apt install curl
```
* [unzip](http://www.info-zip.org/UnZip.html):
``` bash
sudo apt install unzip
```
* [php 7.3](https://php.net):
``` bash
sudo apt install software-properties-common
sudo add-apt-repository ppa:ondrej/php
sudo apt update
sudo apt install php7.3-fpm php7.3-cli php7.3-gd php7.3-imagick php7.3-json php7.3-mbstring php7.3-mysql php7.3-opcache php7.3-readline php7.3-recode php7.3-tidy php7.3-xml php7.3-xmlrpc php7.3-zip
```
* [pip](https://packaging.python.org/en/latest/install_requirements_linux/#installing-pip-setuptools-wheel-with-linux-package-managers):
``` bash
sudo apt install python-pip
```
* [composer](https://getcomposer.org)
``` bash
sudo apt install composer
```
* [mkdocs](https://mkdocs.org) *CiviCRM Docs Publisher expects MkDocs version 0.16.x*
``` bash
sudo -H pip install mkdocs==0.16.3
sudo -H pip install mkdocs-material==1.4.1
sudo -H pip install pygments==2.2.0
sudo -H pip install pymdown-extensions==2.0
```
**Note**: Ensure that MkDocs is installed as root so that it can be accessed from the src/publish.php script (typically invoked as https://docs.civicrm.org/publish.php)*
2. clone this repository to somewhere like /var/www/civicrm-docs and install with composer:
```bash
git clone https://lab.civicrm.org/documentation/docs-publisher.git /var/www/civicrm-docs
cd /var/www/civicrm-docs
composer install
```
3. Set appropriate permissions on web/static.
4. Update the nginx configuration file to point to the php7.1-fpm socket and fix the root:
[- root /var/www/web; -]
[+ root /var/www/civicrm-docs/web; +]
[- fastcgi_pass unix:/var/run/php-fpm.sock; -]
[+ fastcgi_pass unix:/var/run/php/php7.1-fpm.sock; +]
5. Configure the nginx virtual host:
``` bash
cd /etc/nginx/sites-enabled
ln -s /var/www/civicrm-docs/app/config/civicrm-docs.conf civicrm-docs
```
6. Grab the documentation book files:
``` bash
cd /var/www/civicrm-docs/
git clone https://lab.civicrm.org/documentation/docs-books.git books
6. Reload your nginx config and you should be up and running.
......
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
......@@ -20,8 +20,11 @@ class AppKernel extends Kernel {
if (in_array($this->getEnvironment(), ['dev', 'test'], TRUE)) {
$bundles[] = new Symfony\Bundle\DebugBundle\DebugBundle();
$bundles[] = new Symfony\Bundle\WebProfilerBundle\WebProfilerBundle();
$bundles[] = new Sensio\Bundle\DistributionBundle\SensioDistributionBundle();
$bundles[] = new Sensio\Bundle\GeneratorBundle\SensioGeneratorBundle();
$bundles[] = new Symfony\Bundle\MakerBundle\MakerBundle();
}
if ('dev' === $this->getEnvironment()) {
$bundles[] = new Symfony\Bundle\WebServerBundle\WebServerBundle();
}
return $bundles;
......
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
......@@ -23,7 +23,7 @@ framework:
engines: ['twig']
default_locale: "%locale%"
trusted_hosts: ~
trusted_proxies: ~
#trusted_proxies: ~ # Deprecated v3.3
session:
# http://symfony.com/doc/current/reference/configuration/framework.html#handler-id
handler_id: session.handler.native_file
......@@ -66,3 +66,8 @@ swiftmailer:
username: "%mailer_user%"
password: "%mailer_password%"
spool: { type: memory }
# Sensio Framework Configuration
sensio_framework_extra:
router:
annotations: false
......@@ -17,10 +17,10 @@ monolog:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: debug
channels: [!event]
channels: ["!event"]
console:
type: console
channels: [!event, !doctrine]
channels: ["!event", "!doctrine"]
# uncomment to get logging in your browser
# you may have to allow bigger header sizes in your Web server configuration
#firephp:
......
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
server {
server_name localhost;
listen *:8080;
root /var/www/web;
server_name dev.docs.civicrm.org;
root /var/www/civicrm-docs-dev/web;
# For a development configuration, change "app" to "app_dev" everywhere
# below. Then you'll see the Symfony web debug toolbar when viewing pages.
......@@ -26,7 +25,7 @@ server {
}
location ~ ^/app_dev\.php(/|$) {
fastcgi_pass unix:/var/run/php-fpm.sock;
fastcgi_pass unix:/var/run/php/php7.1-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
# When you are using symlinks to link the document root to the
......@@ -50,7 +49,6 @@ server {
return 404;
}
#error_log /var/log/nginx/civicrm-docs-error.log;
#access_log /var/log/nginx/civicrm-docs-access.log;
error_log /var/log/nginx/civicrm-docs-dev-error.log;
access_log /var/log/nginx/civicrm-docs-dev-access.log;
}
server {
server_name docs.civicrm.org;
root /var/www/civicrm-docs/web;
# For a development configuration, change "app" to "app_dev" everywhere
# below. Then you'll see the Symfony web debug toolbar when viewing pages.
# Requests for static book files
# - Book slug can't begin with underscore
# - Book slug can't be "admin"
# - Must begin with three distinct path pieces, separated by forward slashes
location ~ ^/(?!_)(?!admin/)[^/]+/[^/]+/[^/]+ {
# - Use a trailing slash for the $uri to treat paths like directories
# - Then, try to find directories that match our request.
# - If we can't find anything, we send the request to the app and let
# it deal with the rest.
try_files $uri/ $uri /app.php$is_args$args;
}
# requests for Symfony app functionality
location / {
# - Don't use a trailing slash for $uri here. This line is straight from
# the Symfony recommended nginx settings
try_files $uri /app.php$is_args$args;
}
location ~ ^/app\.php(/|$) {
fastcgi_pass unix:/var/run/php/php7.1-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
# When you are using symlinks to link the document root to the
# current version of your application, you should pass the real
# application path instead of the path to the symlink to PHP
# FPM.
# Otherwise, PHP's OPcache may not properly detect changes to
# your PHP files (see https://github.com/zendtech/ZendOptimizerPlus/issues/126
# for more information).
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
# Prevents URIs that include the front controller. This will 404:
# http://domain.tld/app.php/some-path
# Remove the internal directive to allow URIs like this
internal;
}
# return 404 for all other php files not matching the front controller
# this prevents access to other php files you don't want to be accessible.
location ~ \.php$ {
return 404;
}
error_log /var/log/nginx/civicrm-docs-error.log;
access_log /var/log/nginx/civicrm-docs-access.log;
}
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
# Learn more about services, parameters and containers at
# http://symfony.com/doc/current/book/service_container.html
parameters:
books_dir: %kernel.root_dir%/../books
books_dir: "%kernel.root_dir%/../books"
services:
_defaults:
autowire: true
autoconfigure: true
library:
class: AppBundle\Model\Library
arguments:
- %books_dir%
- "%books_dir%"
public: true
github.hook.processor:
class: AppBundle\Utils\GitHubHookProcessor
webhook.processor:
class: AppBundle\Utils\WebhookProcessor
arguments:
-
- '@github.webhook_handler'
- '@gitlab.webbook_handler'
public: true
github.webhook_handler:
class: AppBundle\Utils\WebhookAdapters\GithubHandler
public: true
gitlab.webbook_handler:
class: AppBundle\Utils\WebhookAdapters\GitlabHandler
public: true
mkdocs:
class: AppBundle\Utils\MkDocs
......@@ -28,6 +45,7 @@ services:
- '@mkdocs'
- '@git'
- '@paths'
public: true
filesystem:
class: AppBundle\Utils\FileSystem
......@@ -35,8 +53,8 @@ services:
paths:
class: AppBundle\Utils\Paths
arguments:
- '%kernel.root_dir%'
- '%kernel.cache_dir%'
- "%kernel.root_dir%"
- "%kernel.cache_dir%"
git:
class: AppBundle\Utils\GitTools
......@@ -56,7 +74,7 @@ services:
streamhandler:
class: Monolog\Handler\StreamHandler
arguments:
- %kernel.logs_dir%/publish.log
- "%kernel.logs_dir%/publish.log"
app.exception_listener:
class: AppBundle\EventListener\ExceptionListener
......
#!/usr/bin/env bash
set -x
SCRIPTPATH=$( cd "$(dirname "$0")" ; pwd -P )
cd $SCRIPTPATH/..
sudo -u docs git pull --ff-only origin master
sudo -u docs ./bin/console cache:clear -e prod
#!/bin/bash
find web/static var -exec setfacl -m u:www-data:rwx {} \;
find web/static var -exec setfacl -m u:docs:rwx {} \;
if id "www-data" >/dev/null 2>&1; then
find web/static var -exec setfacl -m u:www-data:rwx {} \;
fi
if id "$USER" >/dev/null 2>&1; then
find web/static var -exec setfacl -m u:$USER:rwx {} \;
fi
if id "co" >/dev/null 2>&1; then
find web/static var -exec setfacl -x u:co {} \;
fi
if id "www-data" >/dev/null 2>&1; then
find web/static var -type d -exec setfacl -m d:u:www-data:rwx {} \;
find web/static var -type d -exec setfacl -m d:u:docs:rwx {} \;
fi
if id "$USER" >/dev/null 2>&1; then
find web/static var -type d -exec setfacl -m d:u:$USER:rwx {} \;
fi
if id "co" >/dev/null 2>&1; then
find web/static var -type d -exec setfacl -x d:u:co {} \;
fi
name: Activity iCal
description: Provides an iCalendar feed of assigned activities per contact
type: extension
langs:
en:
repo: 'https://github.com/twomice/com.joineryhq.activityical'
name: CiviProxy
description: Scripts to install on separate server to police data traffic between CiviCRM on a secure server and the outside world
langs:
en:
repo: 'https://github.com/systopia/CiviProxy'
name: CiviRules
description: Rule based engine to automate administrative processes
langs:
en:
repo: 'https://github.com/CiviCooP/org.civicoop.civirules'
\ No newline at end of file
name: Developer Guide
weight: 10
description: For computer programmers who create and improve functionality within CiviCRM
category: Core
langs:
en:
repo: 'https://github.com/civicrm/civicrm-dev-docs'
name: Fast Action Links
description: Create links to perform custom actions on your search results
langs:
en:
repo: 'https://github.com/MegaphoneJon/com.megaphonetech.fastactionlinks'
\ No newline at end of file
name: Smart Debit
description: Smart Debit Payment Processor (UK Direct Debit Handler)
langs:
en:
repo: 'https://github.com/mattwire/org.civicrm.smartdebit'
\ No newline at end of file
name: SMS conversation
description: Automate SMS conversations with your contacts
type: extension
langs:
en:
repo: https://github.com/3sd/civicrm-sms-conversation
latest: master
stable: master
name: SparkPost
description: Allows CiviCRM to send emails and process bounces through the SparkPost service.
langs:
en:
repo: 'https://github.com/cividesk/com.cividesk.email.sparkpost'
latest: master
stable: master
name: System Administrator Guide
weight: 0
description: For tech savvy people who install, upgrade, and maintain CiviCRM for an organization
category: Core
langs:
en:
repo: 'https://github.com/civicrm/civicrm-sysadmin-guide'
latest: master
stable: master
name: User Guide
weight: -100
description: For staff members who use CiviCRM's web-based interface as part of their job at an organization
category: Core
langs:
en:
repo: 'https://github.com/civicrm/civicrm-user-guide'
default_version: 4.7
versions:
4.7: # This is stored as $slug
name: 4.7 / Latest # If omitted, use $slug
path: latest # If omitted, use a URL-safe version of $slug
branch: master # If omitted, use $slug
redirects: # These are not displayed anywhere
- current
- stable
4.6:
branch: 4.6
name: 4.6 / Long Term Support
redirects:
- lts
ca:
repo: 'https://github.com/babu-cat/civicrm-user-guide-ca'
fr:
repo: 'https://github.com/civicrm-french/civicrm-user-guide'
es:
repo: 'https://github.com/ixiam/civicrm-user-guide-spanish'
name: CiviVolunteer
description: Provides tools for signing up, managing, and tracking volunteers
langs:
en:
repo: 'https://github.com/civicrm/org.civicrm.volunteer'
\ No newline at end of file
......@@ -18,38 +18,28 @@
},
"require": {
"php": "^7.0",
"symfony/symfony": "^3.0",
"symfony/symfony": "^4.1",
"doctrine/orm": "^2.5",
"twig/twig": "^1.33",
"twig/twig": "^2.5",
"doctrine/doctrine-bundle": "^1.6",
"doctrine/doctrine-cache-bundle": "^1.2",
"symfony/swiftmailer-bundle": "^2.3",
"symfony/monolog-bundle": "^2.8",
"sensio/distribution-bundle": "^5.0",
"sensio/framework-extra-bundle": "^3.0.2",
"incenteev/composer-parameter-handler": "^2.0"
"symfony/swiftmailer-bundle": "^3.2",
"symfony/monolog-bundle": "^3.3",
"sensio/framework-extra-bundle": "^5.2",
"incenteev/composer-parameter-handler": "^2.0",
"phpunit/phpunit": "^7.4"
},
"require-dev": {
"sensio/generator-bundle": "^3.0",
"symfony/phpunit-bridge": "^3.0",
"phpunit/phpunit": "^5.7"
"symfony/maker-bundle": "^1.7",
"symfony/phpunit-bridge": "^4.1",
"symfony/web-server-bundle": "^4.1"
},
"scripts": {
"post-install-cmd": [
"Incenteev\\ParameterHandler\\ScriptHandler::buildParameters",
"Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::buildBootstrap",
"Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::clearCache",
"Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installAssets",
"Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installRequirementsFile",
"Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::prepareDeploymentTarget"
"Incenteev\\ParameterHandler\\ScriptHandler::buildParameters"
],
"post-update-cmd": [
"Incenteev\\ParameterHandler\\ScriptHandler::buildParameters",
"Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::buildBootstrap",
"Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::clearCache",
"Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installAssets",
"Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installRequirementsFile",
"Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::prepareDeploymentTarget"
"Incenteev\\ParameterHandler\\ScriptHandler::buildParameters"
]
},
"extra": {
......
This diff is collapsed.
......@@ -10,10 +10,11 @@
<php>
<ini name="error_reporting" value="-1" />
<server name="KERNEL_DIR" value="app/" />
<env name="KERNEL_CLASS" value="AppKernel" />
</php>
<testsuites>
<testsuite name="Project Test Suite">
<testsuite name="CiviCRM Docs Publisher Test Suite">
<directory>tests</directory>
</testsuite>
</testsuites>
......
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
......@@ -2,11 +2,12 @@
namespace AppBundle\Controller;
use AppBundle\Model\WebhookEvent;
use AppBundle\Utils\Publisher;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\Routing\Annotation\Route;
use AppBundle\Model\Library;
......@@ -56,48 +57,46 @@ class PublishController extends Controller {
* @Route("/admin/listen")
*/
public function ListenAction(Request $request) {
$body = $request->getContent();
$event = $request->headers->get('X-GitHub-Event');
$processor = $this->get('github.hook.processor');
try {
$processor->process($event, json_decode($body));
}
catch (\Exception $e) {
$response = "CRITICAL - Skipping the publishing process due to the "
. "following reason: " . $e->getMessage();
return new Response($response, 200);
}
$processor = $this->get('webhook.processor');
$event = $processor->process($request);
$library = $this->get('library');
$identifiers = $library->getIdentifiersByRepo($processor->repo);
if ($identifiers) {
$identifiers = $library->getIdentifiersByRepo($event->getRepo());
if (!$identifiers) {
$msg = "CRITICAL - No books found which match " . $event->getRepo();
return new Response($msg, Response::HTTP_BAD_REQUEST);
}
$this->publisher = $this->get('publisher');
foreach ($identifiers as $identifier) {
$fullIdentifier = "{$identifier}/{$processor->branch}";
$fullIdentifier = sprintf('%s/%s', $identifier, $event->getBranch());
$this->publisher->publish($fullIdentifier);
$this->sendEmail($fullIdentifier);
$this->sendEmail($fullIdentifier, $event);
}
$response = $this->publisher->getMessagesInPlainText();
}
else {
$response = "CRITICAL - No books found which match {$processor->repo}";
}
return new Response($response, 200);
return new Response($response);
}
/**
* Send notification emails after publishing
*
* @param string $identifier
* @param WebhookEvent $event
*/
private function sendEmail(string $identifier) {
private function sendEmail(string $identifier, WebhookEvent $event) {
/**
* Array of strings for email addresses that should receive the
* notification email. If none are specified, then the email will be sent to
* all addresses set in the book's yaml configuration
*/
$extraRecipients = $this->get('github.hook.processor')->recipients;
$extraRecipients = $event->getNotificationRecipients();
$commits = $event->getCommits();
$library = $this->get('library');
$messages = $this->get('publisher')->getMessages();
$parts = $library::parseIdentifier($identifier);
......@@ -113,10 +112,10 @@ class PublishController extends Controller {
'publishURLBase' => $webPath,
'status' => $subject,
'messages' => $messages,
'commits' => $commits,
];
$body = $this->renderView('AppBundle:Emails:notify.html.twig', $renderParams);
$mail = \Swift_Message::newInstance()
->setSubject($subject)
$mail = (new \Swift_Message($subject))
->setFrom('no-reply@civicrm.org', "CiviCRM docs")
->setTo($recipients)
->setBody($body, 'text/html');
......
......@@ -3,7 +3,7 @@
namespace AppBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\Routing\Annotation\Route;
class ReadController extends Controller {
......
File mode changed from 100644 to 100755
......@@ -15,27 +15,32 @@ class Book {
public $slug;
/**
* @var string The title of the book, taken from the "name"
* @var string
* The title of the book, taken from the "name"
*/
public $name;
/**
* @var string Short phrase describing the book, taken from the
* @var string
* Short phrase describing the book, taken from the
*/
public $description;
/**
* @var array An array (without keys of Language objects to
* @var Language[]
* An array (without keys of Language objects to
*/
public $languages;
/**
* @var int Used to sort books
* @var int
* Used to sort books
*/
public $weight;
/**
* @var string (e.g. "Core", "Extensions") Should be in sentence case
* @var string
* (e.g. "Core", "Extensions") Should be in sentence case
*/
public $category;
......
......@@ -4,15 +4,17 @@ namespace AppBundle\Model;
use AppBundle\Utils\LocaleTools;
class Language {
class Language implements \Countable {
/**
* @var string The URL to the git repository for this language
* @var string
* The URL to the git repository for this language
*/
public $repo;
/**
* @var array An array (without keys) of Version objects
* @var Version[]
* An array (without keys) of Version objects
*/
public $versions;
......@@ -25,12 +27,20 @@ class Language {
/**
*
* @var array
* @var string[]
* Email addresses for people who would like to receive a notification any
* time a version within this language is published
*/
public $watchers = array();
/**
* Implement a count() method.
*/
public function count() {
if (is_array($this->versions)) {
return count($this->versions);
}
}
/**
* Initialize a language with values in it.
*
......@@ -69,8 +79,8 @@ class Language {
}
// If no versions were defined, then add one version (with default values)
if (count($this->versions) == 0) {
$this->versions[] = new Version();
if (empty($this->versions)) {
$this->versions[] = new Version('latest', 'Latest', 'latest', 'master', ['stable', 'current']);
}
}
......@@ -171,7 +181,7 @@ class Language {
* @return bool
*/
public function isMultiVersion() {
return count($this->versions) > 1;
return $this->count() > 1;
}
/**
......@@ -180,7 +190,7 @@ class Language {
* @return integer
*/
public function countVersions() {
return count($this->versions);
return $this->count();
}
/**
......
......@@ -7,7 +7,7 @@ use Symfony\Component\Finder\Finder;
class Library {
/**
* @var array
* @var Book[]
* An array (without keys) of Book objects to represent all the books in
* the system.
*/
......@@ -68,9 +68,7 @@ class Library {
$rows = array();
foreach ($this->books as $book) {
foreach ($book->languages as $language) {
/* @var \AppBundle\Model\Language $language */
foreach ($language->versions as $version) {
/* @var \AppBundle\Model\Version $version */
$key = "$book->slug/$language->code/$version->branch";
$row = array(
'book' => $book->name,
......
......@@ -41,7 +41,7 @@ class Version {
public $branch;
/**
* @var array
* @var string[]
* An array (without keys) of strings which represent redirects to this
* version of the book.
* (e.g. ["latest", "current"])
......@@ -64,15 +64,15 @@ class Version {
* automatically add an alias for $name.
*
* @param string $slug
* See Version::slug
* @see Version::slug
* @param string $name
* See Version::name
* @see Version::name
* @param null $path
* See Version::path
* @see Version::path
* @param string $branch
* See Version::branch
* @see Version::branch
* @param array $redirects
* See Version::redirects
* @see Version::redirects
*/
public function __construct($slug = 'latest', $name = 'Latest', $path = NULL, $branch = 'master', $redirects = []) {
$this->slug = $slug;
......@@ -92,9 +92,6 @@ class Version {
$redirects = array($redirects);
}
// Remove alias for $path if it exists
unset($redirects[$this->path]);
// Add alias for $branch (e.g. so urls with "master" will work correctly)
$redirects[] = $this->branch;
......@@ -106,8 +103,11 @@ class Version {
$redirect = StringTools::urlSafe($redirect);
}
// Make sure we don't have any duplicate branches
// Make sure we don't have any duplicate redirects
$this->redirects = array_unique($redirects);
// Ensure that $path is not a redirect (to avoid infinite redirect loops)
$this->redirects = array_diff($this->redirects, [$this->path]);
}
/**
......
<?php
namespace AppBundle\Model;
class WebhookEvent {
const SOURCE_GITHUB = 'Github';
const SOURCE_GITLAB = 'Gitlab';
/**
* @var string
* Where did the hook original, e.g. github
*/
protected $source = '';
/**
* @var string
* What sort of event is it, for example "push"
*/
protected $type = '';
/**
* @var string
* The repo this event was fired from
*/
protected $repo = '';
/**
* @var string
* The branch the event was fired from
*/
protected $branch = '';
/**
* @var \stdClass[]
* An array of commits in the event, each commit will have properties "ID",
* "author" and "message"
*/
protected $commits = [];
/**
* @return string
*/
public function getSource(): string {
return $this->source;
}
/**
* @param string $source
* @return $this
*/
public function setSource(string $source) {
$this->source = $source;
return $this;
}
/**
* @return string
*/
public function getType(): string {
return $this->type;
}
/**
* @param string $type
* @return $this
*/
public function setType(string $type) {
$this->type = $type;
return $this;
}
/**
* @return string
*/
public function getRepo(): string {
return $this->repo;
}
/**
* @param string $repo
* @return $this
*/
public function setRepo(string $repo) {
$this->repo = $repo;
return $this;
}
/**
* @return string
*/
public function getBranch(): string {
return $this->branch;
}
/**
* @param string $branch
* @return $this
*/
public function setBranch(string $branch) {
$this->branch = $branch;
return $this;
}
/**
* @param array $commit
*/
public function addCommit(array $commit) {
$this->commits[] = $commit;
}
/**
* @param \stdClass[] $commits
*/
public function setCommits(array $commits) {
$this->commits = $commits;
}
/**
* @return \stdClass[]
*/
public function getCommits() {
return $this->commits;
}
/**
* @return array
*/
public function getCommitMessages() {
return array_column($this->getCommits(), 'message');
}
/**
* @return array
* Email address of all those who should be notified about the event
*/
public function getNotificationRecipients() {
$recipients = [];
foreach ($this->getCommits() as $commit) {
$author = $commit->author ?? NULL;
if (property_exists($author, 'email')) {
$recipients[] = $author->email;
}
}
// filter out mails that start with "do not reply"
$recipients = preg_grep('/^(donot|no)reply@/', $recipients, PREG_GREP_INVERT);
return array_unique($recipients);
}
}
File mode changed from 100644 to 100755
<p><strong>Note from
<a href="{{ publishURLBase }}">{{ publishURLBase }}</a>:<br />
{{ status }}</strong>
<p>
<strong>
Note from <a href="{{ publishURLBase }}">{{ publishURLBase }}</a>:
<br/>
{{ status }}
</strong>
</p>
<p>Please check the publish log for any errors:</p>
<h4>Messages:</h4>
<ul>
{% for message in messages %}
<li><strong>{{ message.label }}:</strong> {{ message.content|raw }}</li>
{% endfor %}
</ul>
<p>You are receiving this message because either (a) you have made commits
included in the changes currently being published, or (b) your email address
is set for notification in this book's repository.</p>
<p>If you have questions, please contact the CiviCRM documentation working
group here:<br />
<h4>Commits:</h4>
<ul>
{% for commit in commits %}
<li>
<strong><a href="{{ commit.url }}">{{ commit.id }}</a></strong> |
{{ commit.message }} | {{ commit.author.name }}
</li>
{% endfor %}
</ul>
<p>
You are receiving this message because either (a) you have made commits
included in the changes currently being published, or (b) your email address
is set for notification in this book's repository.
</p>
<p>If you have questions, please contact the CiviCRM documentation working group
here:
<br/>
<a href='https://chat.civicrm.org/civicrm/channels/documentation'>
https://chat.civicrm.org/civicrm/channels/documentation</a></p>
https://chat.civicrm.org/civicrm/channels/documentation
</a>
</p>
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
<?php
namespace AppBundle\Utils;
class GitHubHookProcessor {
/**
* @var array of strings for email addresses of people to notify
*/
public $recipients = array();
/**
* @var string the URL for the repository
*/
public $repo;
/**
* @var string the name of the branch to publish
*/
public $branch;
/**
* Constructor
*/
public function __construct() {
}
/**
* Process a GitHub webhook
*
* @param string $event
* e.g. 'pull_request', 'push'
*
* @param mixed $payload
* An object given by json_decode()
*
* @throws \Exception
*/
public function process($event, $payload) {
if (empty($payload)) {
throw new \Exception("No payload data supplied");
}