This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

Development

Welcome to the development corner of the YMCA Website Services distribution.

For YMCA Associations

For Developers

For QA Engineers


Community Guidelines

Best Practices

Getting Started with YMCA Website Services Development

Whether you are just getting started with YMCA Website Services or need to test a feature in a stable environment, the YMCA Website Services Core Team maintains a number of Sandboxes that you can use.

Processes & Components

Environment Setup

Contributing to YMCA Website Services

Working with Existing Functionality

Adding and Removing Functionality

Dependency Management

Decoupling YMCA Website Services

Ongoing Maintenance

Releases

Update Processes & Notices

These documents are for old versions of YMCA Website Services, but may contain useful information for troubleshooting future update issues.

1 - Onboarding

Welcome to YMCA Website Services

List of migrated repositories/projects

In 2022, maintenance of the distribution moved from Open Y LLC to Y-USA. With this, repository locations have changed:

How to start developing Open Y

In order to get a copy of the latest development version of the distribution, please follow steps from YUSA OpenY README.

Pay attention Open Y has a modular structure, so if you plan changes to specific component - create Pull Request/Merge Request in respective project or repository, based on component’s composer.json data.

In order to test specific component, create a PR to yusaopeny and add a reference in composer.json of Open Y in order for the build system to start using updated component.

QA sandboxes for Open Y

The YMCA Website Services core team manages sandboxes for various configurations of the distribution to facilitate evaluation, to help with QA, and enable investigation of issues.

How to start developing Virtual Y

Get started with the README

QA sandboxes for Virtual Y

How to start developing Membership Framework

Get started with the README

QA sandboxes for Membership Framework

How to start developing Activity Finder

Activity Finder is installed with the distribution by default.

Get started with the README

QA Sandboxes for Activity Finder

2 - 3rd-party dependencies

YMCA Website Services’s system requirements generally track those of Drupal with some occasional more opinionated recommendations.

General Requirements

Supported versions may differ based on your Drupal version.

Recommended for advanced functionality, but not required:

  • Apache SOLR search server
    • Version 4.9.1 and version 8 have been tested for Activity Finder. Other versions are works in progress.

For high load/performance sites

See also Drupal’s recommendations for managing site performance and scalability.

For development

See our installation instructions for a full walkthrough of these tools.

Software libraries and frameworks

YMCA Website Services leverages many other open source frameworks including, but not limited to:

3 - Acceptance Testing

YMCA Website Services is a big distribution with a large amount of modules, components, subsystems, and business processes, therefore we have to take appropriate steps to ensure the stability of major functionality during development.

For the automated tests we have created General Checks template on GitHub every developer should follow to get review approval from YMCA Website Services core team. However, General Checks are for testing functionality for the current proposed change only, not for Regression Testing.

For regression testing, Behat tests in this flow are provided automatically on each build by YMCA Website Services community.

Every pull request should include a testing plan prior to release into YMCA Website Services. This plan should cover the testing of all workflows and functionality to ensure that they continue to work with any new code or change implemented. This is because it is possible for conflicts to occur between elements of YMCA Website Services, Drupal Modules, and Drupal Core. These pull request testing plans will increase productivity and decrease effort for manual Acceptance Testing of upcoming Releases. This testing plan should cover specific features and functionality that is likely to cause regression issues post-release or post-upgrade to the latest version of YMCA Website Services once this new code is implemented.

Example of testing plan: If the Drupal core is updated it is important to gather all Drupal core Release Notes since last release core upgrade for YMCA Website Services and analyze important issues fixed. Example - in case if you are doing upgrade from latest 8.4.0 to 8.4.4:

This means the list of systems should be tested are

  • multilingual
  • postgreSQL support
  • migration
  • taxonomy
  • ckeditor
  • composer

This list could be extended by analyzing some highly important parts of YMCA Website Services distributions that depends from the above subsystems. It is not required to spend time on every module that has a dependency taxonomy, but it is important to test at least one impacted module to ensure it is still working post-implementation. In case if there is a Behat test already created for the subsystem in a list then a manual test could be skipped as long as the build is not failing due to the module or element covered in the associated Behat test.

How to choose which modules to test: These can be a random selection from the list of systems impacted, or one of the oldest modules in a system impacted. This is because there is a higher chance that a minor change could cause a regression issue for the modules that have not received recent or regular updates.

The oldest modules(contrib modules) that have dependencies from the above list should also be updated, but to improve productivity, these updates should only be initiated if there is a security issue or a module stopped working because of the subsystems getting updated within an upcoming release. In case if a respective module update creates more issues that the older version of said module - then it is better to keep the old module and fix an associated regression bug. Tip: usually a new version of the module already contains a bug fix, so adding a patch from the drupal.org to composer.json of the YMCA Website Services distribution is preferred to get distribution released. Keep in mind, you will need to create a follow-up task for the module to be updated after release.

After creating list of modules that could introduce regression issues it is highly recommended to follow Quick-start section of the module’s readme files, that usually is shipped with modules. Example for the location_finder. In case if a module has no Quick-start or Acceptance testing section in readme - it is important to test at least one place where functionality of the module should be working. It is highly recommended to add this manual test steps as a follow-up task, new issue or even better - create Pull Request with changes to readme into YMCA Website Services repository. For the sake of performance, adding step by step how-to to the respective module’s README.md file is highly recommended. It takes only a few minutes to write a couple of lines of documentation which will greatly help others with future contributions and changes.

Optional, but greatly appreciated: Add a Drupal tour for the how-to, created in README will benefit future YMCA Website Services users and developers. Having a tour for the business functionality is highly recommended to ship with the component - it creates an in-site visual guided documentation and helps to decrease time for the Acceptance testing.

And last, but not the lease - adding Behat tests to the system will ensure functionality is tested on every pull request, on every CI build in the future.

Rule

Every release of YMCA Website Services since 8.1.9 should include list of subsystems, changed in release for the community to be aware of the possible regressions on their end.

4 - anti spam protection

In order to protect YMCA Website Services customers, we have added anti-spam protection based on CAPTCHA and Google reCAPTCHA out of the box in YMCA Website Services core

You can check the tutorial for how to install and configure reCaptcha on your site.

In the majority of cases having the above configuration in place will protect you from 99% of spam, unless there is human-entered spam that has no protection. To overcome some human-based spam you should use blacklist logic for blocking email domains, used in spam messages.

For that, you can use the Protected Submissions module module, which allows you to harden all submissions on a site with a list of stop words as well as per-language settings.

Virtual Y use case

In order to overcome caching issues, Virtual Y uses the simple_recaptcha module which could be used in similar cases.

The CAPTCHA + reCAPTCHA module solution has presented some reliability issues. The most recent discussion and fix from drupal.org has also not reliably resolved issues for some clients.

At some point, the “Simple reCaptcha” module was used on a project and had no issues, so we’ve started to replace the “CAPTCHA” + “reCAPTCHA” modules with “Simple reCAPTCHA”.

5 - Code of Conduct and Best Practices

The YMCA Website Services community aims to build from the methods and best practices of other open-source projects, such as the Drupal community and the Drupal Ukrainian community.

Bylaws

For the OpenY distribution we have Terms of Use and Participant Agreement.

Development

To understand how we use and develop technologies, refer to the documents below:

JavaScript Code Standards

6 - Code Review Quality Best Practices

This document serves as an addition to our Code of Conduct and Best Practices. It is more technical and in-depth for specific cases that were discussed during code quality review processes the YMCA Website Services team has in place. During this process, all code should be reviewed by 1-2 developers before being merged into the YMCA Website Services codebase.

General Rules

Components in YMCA Website Services (whether modules, themes, or other code structures) should be, as much as possible, reusable and atomic. All features, content types, settings, styles, etc. should be bundled together to create a cohesive component.

  1. General naming conventions
    1. Features module naming
      1. openy_${entity_type|abbr}_${entity_bundle|abbr}_${feature|optional}
        1. Example: openy_node_blog_feature
        2. openy_prgf_sc_feature -> OpenY Paragraph Simple Content (name within yml)
    2. Fields naming (<=20 chars)
      1. field_${entity_type|abbr}_${entity_bundle|abbr}_{name|abbr}
        1. Example: field_prgf_sc_body
    3. All descriptions are mandatory!
  2. Module naming conventions - Depending on the context we should choose the name from this list:
    1. ${project_name|abbr}_${business_name|abbr} - when the code looks like legacy and has specifics that are not ready to be open-sourced
    2. openy_${business_name|abbr} - when the code is ready to be ejected to OpenY package
    3. ${business_name} - when the code is so abstract that it has no connection to OpenY and is ready to be hosted on Drupal.org as an independent project.

Code Sharing

To support reuse by the community, the MODULE-NAME should relate to the business logic of the module. It is not good to create modules by abstracting them out of the business. All modules that have been shared to drupal.org from past projects were possible to share only because they represent some feature, tied to a business need. For example:

  • personify - module for SOAP related methods for working with Personify API
  • acrypt - Asymmetric crypt algorithm

and so on.

PHP

Return early pattern

To keep readability in functions and methods, it is wise to return early if simple conditions apply that can be checked at the beginning of a method:

<?php

function foo($bar, $baz)
{
    if ($foo) {
        // logic goes here
        return $calculated_value;
    } else {
        return null;
    }
}
?>

It’s better to return early, keeping indentation and brainpower needed to follow the code low.

<?php

function foo($bar, $baz)
{
    if (!$foo) {
        return null;
    }

    // logic goes here
    return $calculated_value;
}
?>

Define early pattern

When you have a condition that aims to change the value of a variable without additional logic, get rid of if else elseif code and instead define your variable early and change it via conditions.

Before:

if ($a = 'hello') {
 $text = 'Welcome to site';
}
else {
 $text = 'Register please';
}

After:

$text = 'Register please';
if ($a = 'hello') {
 $text = 'Welcome to site';
}

Null Checks with isset

isset() verifies if set and not null. There is no need to do additional verification against NULL.

Before:

...
'video' => (isset($feed['profile_media_videos']) || $feed['profile_media_videos'] != NULL) ? $feed['profile_media_videos'] : '',
...

After:

...
'video' => (isset($feed['profile_media_videos'])) ? $feed['profile_media_videos'] : '',
...

Dependency Injection

For the decoupled and easier to upgrade code in Drupal 8+ Dependency injection should be used instead of calling methods from services statically.

See the Drupal API Overview of the Dependency Injection Container and Services.

Before:

...
$node = Drupal::entityTypeManager()->getStorage('node')->load($result->getField('nid')->getValues()[0]);
...

After:

...

$node = $this->entityTypeManager->getStorage('node')->load($result->getField('nid')->getValues()[0]);
...

Creating meaningful log messages

To provide useful logging for site managers, we need to write meaningful log messages with a proper context.

Before:

...
        if($type == 'program') {

          if ($feed['profile_media_videos'] != NULL || $feed['profile_media_images'] != NULL) {
          \Drupal::logger('272')->notice($type);
...

After:

...
        if($type == 'program') {

          if ($feed['profile_media_videos'] != NULL || $feed['profile_media_images'] != NULL) {
          \Drupal::logger('form_import')->notice("FORM IMPORT: type is $type");
...

Maintaining an Upgrade Path

All changes in configurations should be added to appropriate hook_update_N to update already existing environments. We suggest using the Config Importer and Tools package for working with hook_update_N.

Install files

openy.install in profile

In this file, we should put updates that are related to the distribution in general and don’t fit into any feature.

  • Enable/Disable module
  • General configs

openy_*.install in modules

If you update some configuration for a specific feature, make sure that you put updates into this file in the appropriate module.

Config Management

Revert only specific property from config

This is the preferred method of updating configs as it will result in fewer conflicts for upgrading customized YMCA Website Services instances.

With config_import module we can update only part of the full config.

For updating specific property in config use the openy_upgrade_tool.param_updater service:

  1. Find the module where your config lives.
  2. Create a new hook_update_N in the openy_*.install file.
  3. In that hook add the update code (for example):
$config = drupal_get_path('module', 'openy_media_image') . '/config/install/views.view.images_library.yml';
$config_importer = \Drupal::service('openy_upgrade_tool.param_updater');
$config_importer->update($config, 'views.view.images_library', 'display.default.display_options.pager');

Where:

  • $config variable contains path to config with config name, like:
  • views.view.images_library - config name
  • display.default.display_options.pager - config specific property (you can set value from a nested array with variable depth)

Revert full configs

This variant uses extensive config file manipulation and increases the time for an upgrade.

For updating full config or several configs from directory use the openy_upgrade_tool.importer service:

$config_dir = drupal_get_path('module', 'openy_media_image') . '/config/install';
$config_importer = \Drupal::service('openy_upgrade_tool.importer');
$config_importer->setDirectory($config_dir);
$config_importer->importConfigs(['views.view.images_library']);

Where:

  • $config_dir - path to directory with config
  • views.view.images_library - config name

Also you can update several configs from a directory:

$config_importer->importConfigs([
  'views.view.images_library',
  'views.view.example_view',
]);

JavaScript includes

image

7 - Colorways

What goes into making the selectable colorways in Layout Builder.

CSS Variables

Base variables

We start by defining a base set of colors based on the “Y Color Wheel and Neighbored Color Zones” from the “Websites & Platforms Style Guide”, available in the YMCA Brand Resource Center.

A color wheel with labels corresponding to the official YMCA colors.

Note: RGB variable values are not complete color definitions and must be wrapped in rgb{a}(), like background-color: rgb(var(--ylb-color-rgb-red-dark), 0.5);.

:root {
    --ylb-color-red-dark: #a92b31;
    --ylb-color-rgb-red-dark: 169, 43, 49;
    --ylb-color-red: #ed1c24;
    --ylb-color-rgb-red: 237, 28, 36;
    --ylb-color-red-light: #f15922;
    --ylb-color-rgb-red-light: 241, 89, 34;
    --ylb-color-orange-dark: #dd5828;
    --ylb-color-rgb-orange-dark: 221, 88, 40;
    --ylb-color-orange: #f47920;
    --ylb-color-rgb-orange: 244, 121, 32;
    --ylb-color-orange-light: #fcaf17;
    --ylb-color-rgb-orange-light: 252, 175, 23;
    --ylb-color-green-dark: #006b6b;
    --ylb-color-rgb-green-dark: 0, 107, 107;
    --ylb-color-green: #01a490;
    --ylb-color-rgb-green: 1, 164, 144;
    --ylb-color-green-light: #20bdbe;
    --ylb-color-rgb-green-light: 32, 189, 190;
    --ylb-color-blue-dark: #0060af;
    --ylb-color-rgb-blue-dark: 0, 96, 175;
    --ylb-color-blue: #0089d0;
    --ylb-color-rgb-blue: 0, 137, 208;
    --ylb-color-blue-light: #00aeef;
    --ylb-color-rgb-blue-light: 0, 174, 239;
    --ylb-color-purple-dark: #5c2e91;
    --ylb-color-rgb-purple-dark: 92, 46, 145;
    --ylb-color-purple: #92278f;
    --ylb-color-rgb-purple: 146, 39, 143;
    --ylb-color-purple-light: #c6168d;
    --ylb-color-rgb-purple-light: 198, 22, 141;
    --ylb-color-white: #FFFFFF;
    --ylb-color-rgb-white: 255, 255, 255;
    --ylb-color-light-grey-1: #f2f2f2;
    --ylb-color-rgb-light-grey-1: 242, 242, 242;
    --ylb-color-light-grey-2: #e7e7e7;
    --ylb-color-rgb-light-grey-2: 231, 231, 231;
    --ylb-color-light-grey-3: #cccccc;
    --ylb-color-rgb-light-grey-3: 204, 204, 204;
    --ylb-color-grey-1: #636466;
    --ylb-color-rgb-grey-1: 99, 100, 102;
    --ylb-color-grey-2: #4F4F4F;
    --ylb-color-rgb-grey-2: 79, 79, 79;
    --ylb-color-grey-3: #3F4042;
    --ylb-color-rgb-grey-3: 63, 64, 66;
    --ylb-color-dark-grey-1: #2F2F2F;
    --ylb-color-rgb-dark-grey-1: 47, 47, 47;
    --ylb-color-dark-grey-2: #231F20;
    --ylb-color-rgb-dark-grey-2: 35, 31, 32;
    --ylb-color-black: #000000;
    --ylb-color-rgb-black: 0, 0, 0;
}

Colorway variables

Each colorway begins with four initial colors, derived from the above color wheel:

  • PrimaryColor
  • SecondaryColor
  • TertiaryColor
  • PartnerColor

All page elements should be composed of these four variables, with “primary/secondary/tertiary” providing complimentary colors and “partner” providing a complimentary option for buttons or other calls to action.

Each variable is prefixed with ws. RGB versions of these four options are provided for use with rgba() styles.

Additionally, 5 variables are used to more specifically define the gradients in the Y logo:

  • LogoChevronDark
  • LogoChevronMid
  • LogoChevronLight
  • LogoTriangleDark
  • LogoTriangleLight

These variables should not be used in page components outside the logo. The Canadian Y logo does not change colors, and therefore these extra colors are not needed for Canadian colorways.

All together, these variables make up a colorway:

--wsPrimaryColor
--wsPrimaryColorRGB
--wsSecondaryColor
--wsSecondaryColorRGB
--wsTertiaryColor
--wsTertiaryColorRGB
--wsPartnerColor
--wsPartnerColorRGB
--wsLogoChevronDark
--wsLogoChevronMid
--wsLogoChevronLight
--wsLogoTriangleDark
--wsLogoTriangleLight

These variables should reference base variables, or other colors provided. Once combined, the full colorway definition should look like this:

:root {
  --wsPrimaryColor: var(--ylb-color-blue-dark);
  --wsPrimaryColorRGB: var(--ylb-color-rgb-blue-dark);
  --wsSecondaryColor: var(--ylb-color-blue);
  --wsSecondaryColorRGB: var(--ylb-color-rgb-blue);
  --wsTertiaryColor: var(--ylb-color-blue-light);
  --wsTertiaryColorRGB: var(--ylb-color-rgb-blue-light);
  --wsPartnerColor: var(--ylb-color-purple-dark);
  --wsPartnerColorRGB: var(--ylb-color-rgb-purple-dark);
  --wsLogoChevronDark: var(--ylb-color-blue-dark);
  --wsLogoChevronMid: var(--ylb-color-blue);
  --wsLogoChevronLight: var(--ylb-color-blue-light);
  --wsLogoTriangleDark: var(--ylb-color-purple-dark);
  --wsLogoTriangleLight: var(--ylb-color-purple-light);
}

Logo Colors

In order to provide consistency across colorways and reduce code duplication, the logo has been decomposed into 6 sections:

  • “the”
  • “chevron”
  • “ymca”
  • “triangle”
  • “registeredtm”
  • “areas-of-impact”

The “chevron” and “triangle” components are composed of radialGradient elements which leverage the additional wsLogo variables defined above. The other components use the existing colorway variables. Each component is a path with an id and the color defined in a fill.

The YMCA logo with labels corresponding to the colors used in each component as described in text below.

  • #logo-the uses --wsSecondaryColor
  • #logo-chevron uses a gradient composed of (from top to bottom) --wsLogoChevronLight, --wsLogoChevronMid, and --wsLogoChevronDark
  • #logo-ymca uses --wsPartnerColor
  • #logo-triangle uses a gradient composed of (from left to right) --wsLogoTriangleLight and --wsLogoTriangleDark
  • #logo-registeredtm uses –wsPartnerColor`
  • #logo-areas-of-interest uses --wsSecondaryColor

Y Styles

Each “Y Styles” option enables a different library, as seen in y_lb.ws_style_option.yml. Those libraries can be overridden by a custom theme if necessary.

8 - Composer

Please always make sure composer.lock file is updated after any changes in composer.json file. You can use composer update command to update any package, in this case composer will take care about updating of composer.lock file.

composer update drupal/metatag

Also you can use composer update --lock command to force updating of composer.lock file according to dependencies in composer.json.

Please check official composer documentation for details: https://getcomposer.org/doc/01-basic-usage.md

9 - Composer version constraints for YMCA Website Services

In 2020, due to changes in Drupal core release management and demand from YMCA Website Services customers to improve upgrade path flexibility and stability, the YMCA Website Services team added extended composer version constraints to our composer.json.

Examples from composer.json:

  • "drupal/ckeditor_bootstrap_buttons": "^1.2 || ^2.0.0", - this line means previous version was 1.2 or any 1.x starting from 1.2, and latest tested - 2.0.0 with allowed any stable 2.x starting from 2.0.0
  • "drupal/custom_formatters": "^3.0 || ^3.0@beta", - tested with 3.0 beta of custom_formatters and allowed any 3.x starting from 3.0 (when it will be released)

By having multiple OR (||) conditions we are providing information for developers on which versions could be used for upgrades. There are cases when the latest, even stable version of dependency could be incompatible with some other functionality and it makes sense to keep the version older while functionality is in the process of upgrading.

For example, if, for some reason, custom_formatters 3.0 won’t be compatible with any of YMCA Website Services dependencies at the time of release, a developer can select an older beta version in order to proceed with the upgrade.

To select a specific version of a dependency when you do an upgrade of YMCA Website Services, add a dependency and its version alongside YMCA Website Services at the composer require... step.

For example:

from upgrade doc

composer require YCloudYUSA/yusaopeny:NEW_VERSION_HERE --no-update
composer update --prefer-dist --with-dependencies --prefer-stable --no-suggest

then change the dependency version

composer require YCloudYUSA/yusaopeny:NEW_VERSION_HERE --no-update
composer require drupal/custom_formatters:3.0@beta1

You can change any of the dependency versions without upgrading YMCA Website Services by running only the composer require... command for specific dependencies and Drupal Update DB routines afterward.

Check official Composer documentation about version constraints and updating Drupal modules with Composer.

10 - Contributing

The YMCA Website Services distribution is open source, and we welcome contributions from the YMCA Movement, the Drupal community, and beyond. Be sure to check our Community Resources for how to get in touch and our Roadmap to see if your request is already in progress.

Issues

If you have a support request, you’ve found a bug, or you have a feature request you can start in our primary repository, YCloudYUSA/yusaopeny:

If you are able to pinpoint the issue to a specific piece of functionality, you can open an issue on the appropriate module.

Pull Requests

We use the GitHub “Fork and pull model” for community contributions. If you have some time to make a contribution to the project, here are the steps that will help you:

  • Create a fork of YCloudYUSA/yusaopeny.
  • Commit & push changes into your fork.
  • Create new Pull Request.
  • Write steps for review. In this way maintainers can go through steps on build to verify your fix/feature.
    • Ensure steps for review added to README.md file in a module’s/project’s directory if it makes sense to check them on regular basis. Often this is needed for crucial parts of the system which is main business functionality of the component. Example of super simple steps for review see in Quickstart section of location_finder module, please.
  • Wait for a CI build and ask maintainers for review.

Important: make sure your git email is associated with account on drupal.org, otherwise you won’t get commits there.

Merge Requests

Modules on Drupal.org follow their Merge Request process. The Drupal Wiki has in-depth documentation on these processes:

Drupal.org credits

If you would like to get drupal.org credits for your contribution:

  • Create issue on drupal.org
  • Link drupal.org issue to GitHub Pull Request
  • Specify in GitHub Pull Request link to drupal.org issue
  • Once PR has been merged, reviewer will close drupal.org issue with appropriate credits.

11 - Create & Use New View Modes

As with any other entity in Drupal, when it comes to render the rendering it in different contexts, you might want to have specific view modes.

Here you can find instructions how you can add new view modes into embedded entity form on YMCA Website Services distribution.

Create a new View Mode

  1. Go to ‘View modes’ page: Structure -> Display modes -> View modes (or visit the URL: /admin/structure/display-modes/view Configuration project add/update form

Configuration project add/update form

  1. Create new view mode: click ‘Add view mode’ button and select entity type (or visit the URL: /admin/structure/display-modes/view/add

Configuration project add/update form

or after each entity type you can see ‘Add new {Name} view mode’ and click on it Configuration project add/update form

  1. Select “Media” and then give a name to your new view mode (or visit the URL: /admin/structure/display-modes/view/add/media Configuration project add/update form

Use the View Mode

  1. Go to Configuration -> Text editor embed buttons (or visit the URL: /admin/config/content/embed Configuration project add/update form

Configuration project add/update form

  1. Then make sure you enable the new view mode in “Allowed Entity Embed Display plugins”, and at the bottom of the page click “Save”. Configuration project add/update form

12 - Daxko

Relates to: Program Registration (Daxko)

Configuration setting at /admin/config/development/daxko

Account configuration must be setup before the Program Registration paragraph will work.

GroupEx Pro

There are three methods of integrating GroupEx Pro with your YMCA Website Services site. In order from most to least complex/customizable:

  • API integration
  • Embedded schedules
  • Responsive schedule link

GroupEx PRO APIs

YMCA Digital Services with the help of YMCA of the North have developed and adopted a Syncer for Repeat Application which helps to migrate from the GroupEx PRO Public API to the Daxko Group API v1 and pulls data from GroupEx PRO to Program Event Framework.

See open-y-subprojects/openy_daxko_gxp_syncer for how to configure the Syncer.

Embedded schedules

This replaces the deprecated Embedded GroupEx Pro Schedule Paragraph.

Embed code for GroupEx Pro schedules can be found in your GroupEx Pro admin interface.

  • Look for the “New embed” toggle.
    Screenshot showing “New Schedule” and other options in the GroupEx Pro admin.
  • Expand the options and choose any filters or colors that you prefer.
  • Disable the “Fixed Header” option.
    Screenshot showing “Schedule Hosting LInk / Embedded Code for New Schdule” from Daxko
  • Copy the resulting code, that will look something like this, substituting 000 for your own account number, and adding any location or category filters as needed:
    <script>
    var acct = '000'; var loc = ''; var cat = ''; var stylesheet = ''; var hideLastnames = true;
    var jsHost = (("https:" == document.location.protocol) ? "https://" : "http://");
    document.write("<scr" + "ipt src='" + jsHost + "ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js' type='text/javascript'></scr" + "ipt>");
    document.write("<scr" + "ipt>var jQuery = jQuery.noConflict(true);</scr" + "ipt>");
    document.write("<scr" + "ipt src='" + jsHost + "www.groupexpro.com/schedule/embed/schedule_embed_responsive.2.js.php?a=" + acct + "' type='text/javascript'></scr" + "ipt>");
    </script>
    
  • Navigate to your YMCA website.
  • Follow the directions to add a Code Paragraph or a Code Block.
  • Paste the embed code into your block.
  • Save the paragraph/block and the page.

If the pasted code does not appear on the page, ensure your site is updated with this change to enable direct copy/pasting of embed codes.

While the incoming code is controlled by Daxko/GroupEx Pro, many changes can be made with CSS. Try the CSS Editor module (≥2.0.1) which is bundled with the distribution, or work with your development partner to make customizations.

GroupEx Pro also provides direct links to the schedule page. These can be found in the “New Embed” section. Simply copy the link and add it to any link field or button on your site.

13 - Decoupled (external) projects

Inventory of external modules available via Composer

Check all GitHub for the tag openy-decoupled

GitHub hosted

  1. YCloudYUSA/yusaopeny_block_modal - Implements a simple block with a body and title that will be used to display modal windows.
  2. YCloudYUSA/yusaopeny_memberships - Membership Framework for OpenY and Drupal.
  3. YCloudYUSA/yusaopeny_prgf_sidebar_menu - SideBar menu for referencing menu blocks and using in SideBars across different pages.
  4. YCloudYUSA/yusaopeny_loc_finder - Extended Location Finder
  5. Open-Y-subprojects/reqclique_gxp_sync - Reqclique Group Exercise Sync
  6. open-y-subprojects/virtual_y_signaling_server - Signalling server for Virtual Y
  7. open-y-subprojects/openy_daxko_gxp_syncer - Daxko GroupEx PRO v1 API Syncer into Program Event Framework
  8. open-y-subprojects/ynorth_gxp_spots_proxy - Availability Spots Cache Proxy for Groupex PRO embed API Syncer into PEF
  9. open-y-subprojects/openy_node_alert - Alerts APP for YMCA Website Services
  10. open-y-subprojects/openy_focal_point - YMCA Website Services Focal Point routines
  11. open-y-subprojects/shared_content_server - Shared Content Server
  12. ynorth-projects/openy_node_session - YMCA Website Services Node Session
  13. ynorth-projects/openy_repeat - Repeat API for PEF. Schedules APP built in Vue.js
  14. ynorth-projects/openy_pef_gxp_sync - Groupex Pro Embed/OpenY Syncer into PEF
  15. ymcatwincities/ymca_sync - Syncer backend core
  16. YCloudYUSA/yusaopeny_activity_finder - Activity Finder app
  17. ymcatwincities/media_entity_document - Media Entity Document
  18. ynorth-projects/openy_prgf_session_table - if you need to present couple of Sessions in a table view without using any complex app like Schedules or Activity Finder

Drupal.org hosted

  1. drupal/upgrade_tool - YMCA Website Services Upgrade Tool
  2. ymcatwincities/paragraph_skins - Skins component from OpenY. Decoupled to drupal/paragraph_skins
  3. drupal/openy_autocomplete_path - YMCA Website Services Autocomplete Path. Works in Drupal 8 only. Removed from 9.* YMCA Website Services releases.

Decoupling mind-map

YMCA Website Services decoupling

14 - Decoupling components as independent modules

History

In 2019 the YMCA Website Services team started decoupling major components to streamline the distribution and simplify support.

Communication started in the Community Board - Ejecting modules from OpenY distro as independent projects.

The decoupling process is ongoing. See the index of decoupled projects.

In 2021 the YMCA Website Services core team faced coupling blockers in the distribution during the upgrade from Drupal 8 to Drupal 9

To formalize the ongoing development and maintenance strategy, the YMCA Website Services core team shared its decoupling plan with the wider community in mid-2021.

This document elaborates on those processes.

Policy

Process

for creating a new decoupled component

  1. Create a new GitHub/Drupal.org repository.
  2. Work on getting an initial release with at least beta version stability.
  3. Create a composer.json file for the component in order to be able to start using it via composer. See Virtual Y for an example.
  4. Make it available for the public via packagist.org or drupal.org as a release. Ensure podarok is added as a co-maintainer to the respective system.
  5. Suggest adding to YMCA Website Services by opening an issue.
  6. If approved, create a Pull Request adding it as a dependency in composer.json.
  7. Ensure this component is enabled in any of the packages maintained in the YMCA Website Services profile installation
  8. Ask for review and release, according to the release plan.

for decoupling an existing component of YMCA Website Services

Follow the steps above, but:

  • After creating the repo, filter the selected component by running git filter-branch --subdirectory-filter ... from the latest development branch of the YMCA Website Services profile. This keeps credits of work done for this component as a part of the Code of Conduct.
  • After separating the code, ensure the ejected code is not duplicated in the YMCA Website Services profile. Remove duplicated code in the same Pull Request in which you add the new dependency.

Examples

How to update module on Drupal.org

  • Git filter-branch to get a history of changes.
  • Change git origin to Drupal.org project.
  • Create a new branch and push the code to Drupal.org.
  • Create and push tag to Drupal.org. Create a release on drupal.org.
  • Update composer.json in this distribution with a new tag.

How to decouple module from YN to Drupal.org

Example: paragraph_skins

git clone git@github.com:YCloudYUSA/yusaopeny.git decouple
rm -rf decouple_copy && cp -a decouple decouple_copy
cd decouple_copy
git filter-branch --subdirectory-filter docroot/modules/contrib/paragraph_skins
git clean -dfx
git remote remove origin && git remote add origin git@git.drupal.org:project/paragraph_skins.git
git pull origin 8.x-1.x --allow-unrelated-histories
# Resolve conflicts if applicable.
git push origin production:8.x-1.x
# Create tags and release on Drupal.org

How to decouple module from YMCA Website Services to YMCA Website Services Subprojects

Request a repository for the module. Example: shared_content_server

git clone git@github.com:YCloudYUSA/yusaopeny.git decouple
rm -rf decouple_copy && cp -a decouple decouple_copy
cd decouple_copy
git filter-branch --subdirectory-filter docroot/profiles/contrib/openy/modules/custom/SOME_MODULE_HERE
git clean -dfx
git remote remove origin && git remote add origin git@github.com:Open-Y-subprojects/SOME_MODULE_HERE.git
git push origin production
# Create composer.json on the decoupled repository. Example: https://github.com/YCloudYUSA/yusaopeny_activity_finder/blob/4.x/composer.json
git clone git@github.com:ynorth-projects/distribution.git yn-distribution
# Update composer json for distrubution. See below

Example for Activity Finder

References

15 - Dependencies in drupal info.yml

In order to generate composer.json, Drupal.org defines specific rules in the modules info.yml file

If you need to add a dependency to the Drupal.org module you should provide a format:

dependencies:
  - drupal:webform

In this case, your module will have composer dependency to drupal/webform

If you make it:

dependencies:
  - whatevernameyouwish:webform

the Drupal.org packaging routine will replace it with drupal:webform on the fly.

In order to break the dependency on composer level but still tell Drupal core to have module dependency while resolving dependencies during the process of enabling the module, you should use the simplified format:

dependencies:
  - webform

In the above case, composer won’t have any dependencies, but your module will require that the webform module be available in the codebase in order to be enabled by Drupal core.

16 - Deprecating and removing components

Occasionally old code is deprecated from the YMCA Website Services codebase. In order to minimize disruption to existing sites, we use the following process:

  1. Decide - Before removing components from the distribution we gather feedback from the community to protect active projects from having components accidentally removed. This is accomplished via messaging in the YMCA Website Services Slack and discussion on Monthly calls.
  2. Deprecate - Once a decision is made, we notify users that the feature will be removed soon. The deprecated component is moved from the YMCA Website Services package group to the YMCA Website Services (Deprecated) package group. For example: Deprecate Daxko Program Registration Paragraph. Deprecation notices are posted in point and quarterly releases of YMCA Website Services.
  3. Uninstall - Before removing code, components should be uninstalled via an update hook in the distribution and any hard dependencies should be removed. Uninstalls must occur at least one point (fix) release after the deprecation notice.
  4. Remove - Complete removal of the component from the codebase or composer.json should happen at least one quarterly (feature) release after the deprecation notice.

Additionally, the following housekeeping steps should be taken when deprecating a component:

  1. The release where the deprecated component has been uninstalled should be added to the important versions document in the Wiki.
  2. Code should be decoupled to external GitHub repositories with all history of commits, marked as openy-decoupled, and archived.

UX/CX for deprecated components

In order to deliver a high-quality upgrade path and keep the distribution on the bleeding edge of technologies we occasionally replace old and aged components with new ones for a better User eXperience and Content eXperience.

In order to achieve deprecations we have a policy that aims to provide a comfortable migration path for all components of the distribution.

  1. When we create a component that will replace an old one we must introduce a period of overlap, when both components are available in the system for some time (6-18 months usually). This allows users to have time and resources to migrate from the old to the new one before it is removed from the distribution. See the Activity Finder v3 to v4 migration.
  2. Deprecated components are moved to the deprecated modules group in the list of modules at Admin > Extend. Also, we add lifecycle and lifecycle_link to the documentation in every deprecated module in order to provide enough information for the community. See Deprecate openy_gxp.info.yml.
  3. All titles of deprecated components in the Content Editing interface should be renamed to add the suffix (deprecated) to help Content Managers on a daily basis to not chose an old component and use a new one.
    Naming Example
  4. For the majority of content components an automated migration path is expensive and sometimes even impossible, so we have a “lazy migration” practice in our community which puts the responsibility of migration on Content Managers and Strategists. Once new components are available in the distribution all editors should start using them and rebuild old pages by replacing old components with new ones. After the communicated timeframe (6-18 months) old components are removed from the distribution, but if an association needs it the component will be available as an independent—but unsupported—project. It can be supported by a 3rd-party agency or developer as long as it is needed.
  5. After the communicated timeframe (6-18 months) the Core team will remove the component from the distribution and keep it in an independent project for archival reasons. Usually, the project is marked as archived/obsolete in order to clarify that it is not supported and is possibly insecure.
  6. If the normal timeframe (6-18 months) is not achievable due to unforeseeable circumstances, the Core team will add proper notifications and tutorials for the community to help migrate in a comfortable way in a shorter period of time. See the GroupEx Pro API deprecation notice.

17 - Development FAQ

YMCA Website Services Developer FAQ

Local Development

Getting started with a local environment

To start developing you need to obtain the latest YMCA Website Services codebase. See the openy-project repository for the full process.

This video tutorial will walk you through how to initiate a local development environment.

The YMCA Website Services team has pre-built environments and walkthroughs using either Vagrant and VirtualBox or Docker and Docksal. Choose the method that you’re most comfortable with and get started!

Gathering information about your local environment

To best troubleshoot issues, it’s helpful for the YMCA Website Services team to have as much information about your environment as possible. Before you ask for help, watch this tutorial on how to gather that information.

Debugging with Xdebug in your local

The Docksal project maintains detailed information for using Xdebug with VSCode, PHPStorm, and more.

Contributing

Who should I specify for review?

We have a best practice to get at least 2 independent reviews before merging code. Please request a review from the YMCA Website Services Lead Technical Architect (Andrii Podanenko, @podarok) and somebody else (from your team or another YMCA Website Services partner).

Who is responsible for merging?

The YMCA Website Services Lead Technical Architect (Andrii Podanenko, @podarok) is responsible for final approval, merging, and release management on the YMCA Website Services project.

What labels in PRs should I use?

What milestone should I specify?

Why I can’t add labels or specify milestones?

All of these require you to be granted Contributor access to the YMCA Website Services GitHub repository. Contact the YMCA Website Services Lead Technical Architect (Andrii Podanenko, @podarok) to get access. Labels are usually set by the YMCA Website Services Core Team.

Why are the steps for review in Pull Requests so important?

When you send your code for review our team must know both how to review the code and what to test to verify the functionality. You are the only source of truth for how to check functionality. Adding steps for review will help the reviewer and QA team to verify that the issue is resolved.

Why should I add a reference to the GitHub issue in my PR description?

As we are a community-led project, there may be a long time between creating an issue and resolving it in a Pull Request. The reviewer should be able to understand the context and possible discussion around the issue to be resolved with your PR. The more context we have, the better and faster we can review the request.

In what format should I add commits, should I add internal Jira task ID or GitHub issue?

It is important to make commit messages with some sort of sense for the human to read them when digging back in history. Adding any task identifications from the project management system is allowed.

What is the “DeepCode” bot?

DeepCode bot is the automated, machine learning code review system that analyses huge amounts of GitHub repositories and is sometimes useful to find common issues before humans do reviews. It is helpful, but not always necessary to fix issues found by the DeepCode bot because sometimes it fails. If you see a comment be sure to read the report. If the report makes sense, then fix the issue suggested by the bot.

Build Automation & CI

What CI processes does YMCA Website Services have in place?

To get a fully working YMCA Website Services site for the code change you are about to push for review there is a build generating system installed for the YMCA Website Services GitHub repository that automatically generates a dedicated temporary website with your changes applied.

Why are some builds created automatically and some not?

By default, builds are configured for trusted users, so if you are getting a message from the bot like

“Can one of the admins verify this patch? Use “o+k to test” or ‘’t+est this please” for manual build execution."

then your username is not in the allowlist and somebody from the YMCA Website Services Core Team can comment to initiate a build for you. Contact @podarok to get your build generated or your name added to the allowlist.

How do I create a build for my PR?

If you are on the allowlist then simply create a Pull Request from your fork to the YMCA Website Services repository. After up to 30 minutes you’ll receive comments with links to the generated site builds.

When are builds deleted from the server?

Usually, you have a day for the build to be wiped out from the server. If there is an upcoming deadline and many PRs are coming in, the lifetime could be significantly shorter, down to a couple of hours.

Who should I contact to get logs from the build server?

Andrii Podanenko @podarok or Dima Danylevskyi @danylevskyi

What should I do if tests fail?

If you have any concerns with reports generated by the code checkers that are used in YMCA Website Services ask YMCA Website Services Lead Technical Architect Andrii Podanenko to get them resolved. The majority of these systems are works-in-progress and it is helpful to have feedback on them.

How do I install YMCA Website Services on Pantheon hosting

See request from a community. The solution is described in Pantheon’s documentation on nested docroots. We suggest that you maintain your own composer.json with the specified web-root directory, as described in the Pantheon examples.

Upgrade Troubleshooting

See Upgrading to a new version of the distribution for full instructions.

Config is missing

Occasionally, configuration will get removed or otherwise go missing in the upgrade process. For instance, the list of colors could go missing in the Layout Builder styles pane.

A screenshot with missing colors.

Usually, these changes are resolved by update hooks that import new config, but on occasion, these too can fail or break. In that case, we have a few options for resolving the issue:

  1. Re-run the most recent related update hook.
  2. Import the config with drush.
  3. Import the config with the Drupal UI.

The first step in any of this troubleshooting is to try to find the offending config. In this case, searching your codebase for “text-color” might lead you to this config file in y_lb. Now, we can try a few things…

NOTE: These methods could damage your site if not tested. Please take a backup before proceeding.

Re-run an update hook

Often, searching an adjacent .install file can get you an existing update hook to import the missing configuration. In our example case, y_lb_update_9001 imports the one settings file that we’re looking for. It doesn’t matter that the hook is old, if we re-run it, it will import the file in its current state in our file system.

To re-run the update hook (via gist):

drush php-eval "\Drupal::moduleHandler()->loadInclude('y_lb', 'install'); y_lb_update_9001();"

Understanding this command:

Import config with drush

Suppose the target config exists mostly on its own, or you wish to import the entire config of a module (due to a failed install, for instance). In that case, you can use drush config:import with --partial and --source pointing to a module directory, relative to the Drupal root. In this case:

drush config-import --partial --source=modules/contrib/y_lb/config/optional/

Be aware that all configs in that directory will be imported. Targeting a single config file with drush is impossible, although you could also temporarily move the config to its own directory.

Import config with the UI

Another way to import a single configuration file is with the Drupal “Config Synchronization” admin pages. To import a single item:

  • Go to Admin > Configuration > Development > Config Synchronization > Import > Single item (admin/config/development/configuration/single/import).
  • Choose the Configuration type (if you are unsure, choose “Simple Configuration”)
  • Paste in the configuration from the file and click Import.

18 - Drupal 10 update

The update from Drupal 9 to 10 is easier than some, but still comes with some challenges.

The distribution core team has gone through these steps to ensure as smooth of a transition as possible. If your site is up-to-date and using no additional dependencies you may be able to skip right to the update, but otherwise you’ll want to review these steps.

Resources

Review important versions

Step through the distribution’s important versions until you reach 9.2.13.0. You should be running the latest Drupal 9.5.x before you begin the upgrade to 10.

Pre-checks

  1. CKEditor
    1. If any custom/contrib modules are used, CKE5 should likely be done AFTER your D10 upgrade
    2. Contrib checks will NOT be found in the next step, be sure to check these manually
  2. Dependency cleanup
    1. Modules not installed, but in composer.json should be cleaned up to prevent unwanted dependency issues in trying to update.
  3. Admin theme
    1. If your website uses a deprecated admin theme, you should migrate to the Claro theme and test the admin experience. If necessary you can keep the deprecated theme as a contrib package but that is not recommended and won’t be supported by the distribution.

Upgrade Report

  • Install Upgrade Status
    • fin composer show drupal/core | grep versions
    • fin composer require --dev drupal/core-dev:[copy version above] --update-with-all-dependencies
    • fin composer require drupal/upgrade_status
    • fin drush en upgrade_status
  • Run the report
    • /admin/reports/upgrade-status
  • Check if the website is using custom CKEditor plugins with CKEditor Plugin Report

Keep / Kill

  • Based from the report above, determine which modules (if any) could be removed without impacting the site
  • From the remaining, review if the module
    • Has a D10 ready version
    • Has a D10 ready Fork/Patch
    • Has been abandoned
  • Itemize based on the above with notes of efforts to continue using the modules

Custom modules and themes

Patches

  • Review patches in composer.json. Review any that are no longer applying or may be duplicated by the distribution.
  • Carefully review and re-roll custom patches.

Update

At this point you should be ready to update to the latest version of the distribution:

  • Edit the ycloudyusa version in your project root composer.json: "ycloudyusa/yusaopeny":"^10.3",
  • Run composer update
  • If errors occur, review the conflicts, check out the known issues, and attempt to resolve them.
  • Re-run the previous steps until they complete successfully
  • Run drush updb, review the updates, and run them.

Smoke tests

We recommend reviewing critical functionality after the update to ensure any custom functionality still works.

Troubleshooting

Composer issues

Composer can be … tricky. To resolve composer conflicts:

  • If specific modules conflict, try requiring them directly to get more information about the conflict.
  • Make good use of composer why and composer why-not

Update hook conflicts

If you run into an error like this:

> [notice] Update started: y_lb_update_9011

> [error] Configuration core.entity_view_display.node.lb_event.featured depends on the core.entity_view_mode.node.featured configuration that will not exist after import.

you may be able to resolve it yourself.

Breaking down the error message:

  • core.entity_view_mode.node.featured is missing, which is blocking y_lb_update_9011 from installing core.entity_view_display.node.lb_event.featured
  • We need to figure out where core.entity_view_mode.node.featured should be coming from, so we can search our code for that.
    • Use the “Find in files” command in your IDE to search docroot/modules, or
    • from the command line:
      ╰─ grep -rI "core.entity_view_mode.node.featured"
      ./contrib/ws_event/config/optional/core.entity_view_display.node.lb_event.featured.yml:    - core.entity_view_mode.node.featured
      ./contrib/y_lb_article/config/optional/core.entity_view_display.node.article_lb.featured.yml:    - core.entity_view_mode.node.featured
      
    • Looking at those files in the codebase, they are identical, so we could manually import them from either module. Let’s do it.
  1. Add an update hook to your own custom module like this example.

    // This goes in mymodule.install as the next update hook.
    // Increment the number accordingly.
    function mymodule_update_9000() {
        $path = \Drupal::service('extension.list.module')->getPath('ws_event') . '/config/optional';
        /** @var \Drupal\config_import\ConfigImporterService $config_importer */
        $config_importer = \Drupal::service('config_import.importer');
        $config_importer->setDirectory($path);
        $config_importer->importConfigs([
            'core.entity_view_mode.node.featured',
        ]);
    }
    
  2. Use hook_update_dependencies to ensure this new update runs before the failing one.

    // This also goes in mymodule.install.
    function mymodule_update_dependencies() {
      $dependencies['y_lb'][9011] = [
        'mymodule' => 9000,
      ];
    }
    
  3. Re-run drush updb.

  4. If you run into other missing configs, add them to the list to be imported in update hook and re-run updb.

  5. Consider backporting your customization which led to the challenge of doing this upgrade in order for it to be covered and tested by distribution developers.

19 - Drupal 9 core dependencies version flexibility

This document is no longer updated.

To update the version of Drupal being used on your site independent of YMCA Website Services see Updating Drupal Core via Composer. Be aware that openy/composer.json may set Drupal core version constraints.


February 2021 release tagged Drupal core both 9.0.x and 9.1.x as allowed to be used.

Composer by default is installing the latest stable version, so a command

composer create-project YCloudYUSA/yusaopeny-project:dev-9.2.x-development OPENY --no-interaction

will install YMCA Website Services on latest 9.1.x Drupal core.

If there is a need to stay on Drupal 9.0.x stable core please use

composer create-project YCloudYUSA/yusaopeny-project:dev-9.2.x-development OPENY --no-interaction
cd OPENY
composer require drupal/core:~9.0.7

where 9.0.7 - is a needed version for your YMCA Website Services instance

For modules see Composer-version-constraints-for-Open-Y

20 - Drupal-SA-CORE-2018-004 security update

This document is archived but may contain useful information for troubleshooting future updates. For updated update steps, visit How to upgrade YMCA Website Services.


To update your OpenY site with security fix from Drupal core https://www.drupal.org/SA-CORE-2018-004 OpenY team is suggesting 2 options- via patch and via Drupal core upgrade(or OpenY upgrade). Drupal core upgrade or OpenY upgrade is not always possible, but security issue should be fixed asap. So consider to apply patch and plan OpenY upgrade later.

How to apply the patch

Patching OpenY releases 8.0.1 - 8.1.10 (Drupal cores 8.2.x, 8.3.x, 8.4.x)

For patching your OpenY release, follow steps below:

  • Login to your production server environment via SSH and find docroot folder of your site codebase. If you installed OpenY by following a tutorial - you should: if your site is located in /var/www/html
ssh -l root YOUR_SERVER_DOMAIN_NAME
cd /var/www/html

wget https://raw.githubusercontent.com/YCloudYUSA/yusaopeny-project/8.1.x/scripts/patches/SA-CORE-2018-004.patch

if your site is located in /var/www/openy

ssh -l root YOUR_SERVER_DOMAIN_NAME
cd /var/www/openy

wget https://raw.githubusercontent.com/YCloudYUSA/yusaopeny-project/8.1.x/scripts/patches/SA-CORE-2018-004.patch

Now you are ready to patch your site. But before patching - make a backup of the file which is about to be patched

sudo cp docroot/core/lib/Drupal/Core/Security/RequestSanitizer.php /var/backups/RequestSanitizer.php
sudo cp docroot/core/modules/file/src/Element/ManagedFile.php /var/backups/ManagedFile.php

To patch your site run the command to test if the patch can be applied:

patch -p1 --dry-run < SA-CORE-2018-004.patch

You should see a result

# patch -p1 --dry-run < SA-CORE-2018-004.patch
checking file core/lib/Drupal/Core/Security/RequestSanitizer.php
checking file core/modules/file/src/Element/ManagedFile.php

In case if result different - stop on this step and let us know you have issue. In case if all good proceed with a command below, which will patch your site:

patch -p1 < SA-CORE-2018-004.patch

You should see the same output as previously, but now your site is patched.

TIP: In case if you are using git repository for your site run

git add docroot/core/modules/file/src/Element/ManagedFile.php docroot/core/lib/Drupal/Core/Security && git commit -m "Patching OpenY core" && git push

to store your patched core into your own repository.

==========================

How to patch your Digitalocean OpenY install

In case if you have followed tutorial you should have your OPenY installed on you DigitalOcean server(droplet) in a predictable for current document folder. That’s why we prepared a short how to patch your OpenY site in a most simple way if you are not a Tech Guru, but just a user

  1. Log in as an admin user to your site admin UI by visiting /user/login URI page.
  2. Login to your DigitalOcean cloud console at digitalocean.com and find Access Console in the dropdown for the droplet you are using for the OpenY image
  3. You should see a popup window with a black screen where console asks you for the login. Use root user and a password generated for you upon droplet creation.
  4. After login to a console run the command below, respectively to the version of your Drupal core.

One line script to patch Drupal core for OpenY

Type manually exact line

bash < <(curl -s https://raw.githubusercontent.com/YCloudYUSA/yusaopeny-project/8.1.x/scripts/patches/runSA-CORE-2018-004.sh)

and hit Enter. You should see OpenY was patched message.

21 - Google Custom Search Configuration

The YMCA Website Services release 8.2.4 introduces Google Custom Search (aka Google Programmable Search Engine) for the website out of the box.

Enabling the module

Fresh installations

The search feature is included in the Extended installation type. For Standard see the Existing websites section.

If you are installing a fresh YMCA Website Services website and going through the installation process via the web interface, on the third-party integration step, you can specify a Google Search ID. If you specify the Google Search ID in this form, your site’s search feature will be up and running.

Existing websites

The search feature is not automatically enabled after upgrading a YMCA Website Services website. You have to manually enable it.

To do that:

  1. Log in as an admin (or a user with the administrator role).
  2. Go to the YMCA Website Services package install page (Admin menu > YMCA Website Services > Extend > Install, or /admin/openy/extend/list)
  3. Find the Search package there, tick the checkbox, and submit the form.

Now, the search modules are enabled, and the website header should have a search field. Upon installation, the modules create a Landing page for search results and point the header search form to the page.

Configuring the Google Search modules

  1. Go to the Google Search settings form (Admin menu > YMCA Website Services > Settings > Google Search settings, or /admin/openy/settings/google-search).
  2. Set the value of the Google Search ID field (see the following section for details) and submit the form.

Obtaining Search Engine ID

  1. Go to https://cse.google.com/, register if you haven’t yet, and log in if you aren’t logged in.
  2. Create the Search Engine (this process is explained in Google’s documentation:
    1. Click “New Search Engine”.
    2. Specify the domain of your website (e.g. www.example.com).
    3. Specify the name of the Search Engine (e.g. example.com).
    4. Click “Create”.
  3. On the newly created Search Engine page there is the Search engine ID field. Use this value in the YMCA Website Services Google Search configuration form.

Configuring the Search Engine look and feel

  1. Go to the Look and feel section of the Search Engine
  2. In the Layout tab, select the Full width option and click Save

If this change hasn’t been made, the search results on the website are shown in a popup window.

Dealing with ads

By default, newly created Search engines use the Free Edition (with ads) of the service. As YMCAs are non-profit organizations they have the option to switch to Non-profit Edition of the CSE, where it is possible to disable ads.

If you are already registered as a Non-profit in Google:

  1. From the CSE Control Panel, select the search engine you want to change.
  2. Click Overview then Ads
  3. Toggle the Show Ads option to off.

The Google Custom Search Engine can also be used with Layout Builder:

  1. If you have an existing site, disable the old search page:
    • Go to /search.
    • Remove the URL alias by unchecking Generate automatic URL alias in the sidebar then deleting /search.
    • Uncheck Published and Save to un-publish the page.
  2. Create a new Landing Page (Layout Builder) (node/add/landing_page_lb):
    • Set the Title to “Search”.
    • Ensure Generate automatic URL alias is unchecked in the sidebar and set the alias to /search.
      • If that alias results in an error, you can remove the old one at Admin > Configuration > Search and metadata > URL aliases
    • Check Published then Save and edit layout.
  3. Add a Small Banner to the header with a title for the page, like “Search”.
  4. Add the search results code to the page:
    • In the Body section, Add block and choose Code Block
    • In Code, add the embed code from the CSE configuration. You may need to add an outer div to fit your page layout, for example:
      <div class="paragraph paragraph--type--google-search py-4">
        <script async src="https://cse.google.com/cse.js?cx=[id]"></script>
        <div class="gcse-search"></div>
      </div>
      
    • Save layout and check your page
  5. Change the Google Search config to use your new page:
    • Go to Admin > YMCA Website Services > Settings > Google Search settings (/admin/openy/settings/google-search) and set the Search page id to the node id of your new page.
    • Or, change the config with drush:
      drush cset openy_google_search.settings search_page_id <nid>
      
  6. Test the search box in the Layout Builder page header to ensure the new configuration works as expected.

Advanced setup

Google maintains documentation on how to configure advanced search features

You can add multiple domains to the custom search engine if your association maintains multiple websites, for example, if your camps run at different website domains

You can also add not only the whole website but its parts by specifying patterns like example.com/blog/*. See Update sites in your search engine for details.

Refinements and facets

Use Refinements to narrow the scope of search

Refinements let users filter results according to the categories you provide.

Refinements appear in the search results page as tabs. The content of each tab is configured in the Search features > Refinement section of the Custom Search Control panel.

To set up a dedicated tab in search results for Blog posts do the following:

  1. In the Control panel, go to Search features > Refinements
  2. Click Add
    1. Set the name of the refinement to Blog
    2. Select Search only the sites with this label for How to search sites with this label?
    3. Click Ok
  3. Go to Setup
  4. Find Sites to search, click Add
    1. Add the example.org/blog/* in the text field
    2. Select Blog in the Label dropdown
    3. Select Include just this specific page or URL pattern I have entered
    4. Click Save

The search results page now shows the Blog tab that only shows blog entries relevant to the search term.

Promotions

Use Promotions to highlight a page in searches

Information for developers

Google Custom Search Developers documentation

Enabling via Drush

Use the following snippet to enable the package on existing websites:

drush en openy_google_search

Configuring the module via Drush

Use the following snippet when you install YMCA Website Services via Drush to set the Search Engine ID:

drush site-install openy \
   --account-pass=password \
   --db-url="mysql://user:pass@host:3306/db" \
   --root=/var/www/docroot \
   openy_configure_profile.preset=extended \
   openy_theme_select.theme=openy_rose \
   openy_third_party_services.google_search_engine_id="01234567890123456789:abcedefgh"

The openy_third_party_services.google_search_engine_id parameter sets the Search Engine ID (01234567890123456789:abcedefgh in the example).

Use the following snippet to set the Search Engine ID on already installed websites:

drush config-set openy_google_search.settings google_engine_id "01234567890123456789:abcedefgh"

22 - GroupEx PRO quick start

This document has been moved to ynorth-projects/openy_pef_gxp_sync.

23 - How to contribute large features (back-porting, etc)

These are our best practices for back-porting large features into YMCA Website Services and contributing code for others to use.

Summary

  • The YMCA Website Services core team is excited for you to contribute to the distribution for all to benefit from.
  • There’s a lot that goes into back-porting your code – details below.
  • These steps ensure that we are collaborating while continuing to support YMCA Website Services in a sustainable way.

Before getting started, please keep these notes in mind

  • Back-porting requires a process called decoupling. This is where your developers remove any hard-coded variables or dependencies on any integration from your website code. This makes it so the feature you wish to contribute can work for anyone the broader Y movement. Meaning, as an example , anything that ties into Personify APIs will have to have those hooks replaced with Program Event Framework so that it could function with any CRM source that an YMCA Website Services site might be using.
  • This decoupled code will then need to be thoroughly tested to ensure it can function when not relying on any fee-based, or non-secure, technology or systems .
  • Once the decoupling is complete, the YMCA Website Services core team will need to review every line of code that goes before it goes into the distribution . This helps us ensure it won’t break any of the other elements of YMCA Website Services, and that the code is 100% secure. As of 2019 we have 3 templates in YMCA Website Services that work across mobile, desktop and tablet breakpoints . We need to test new features/code across all these templates to make sure nothing breaks across hundreds of possible use-case scenarios ( example : adding a schedule block to a location landing page using the Carnation template when on the mobile breakpoint that is powered by ActiveNet through Program Event Framework…)
  • Once a feature is in YMCA Website Services, someone must pay to maintain that code . Does this code rely on any other Drupal modules to function? What if there’s an update to that module? That update needs to be tested to ensure it’s compatible with the now contributed code – and if it breaks, we have to write new code to fix it. What if there’s a security patch that involves the contributed code? We would then have to spend time applying the patch, etc.
  • Is your customization a new feature or a replacement of existing YMCA Website Services functionality/UX? We prefer you have A/B testing data demonstrating that your customization is a clear improvement over the current YMCA Website Services experience. There are many ways to run AB tests so please consult with the YMCA Website Services team on your hypothesis, method, and success criteria to ensure that the results are valid and reliable.

Steps/process for back-porting code into YMCA Website Services

Most problems have at least a generic component and can be approached in part through abstracted development.

We recommend beginning development with an eye toward these “abstracted” solutions - providing configuration instead of static templates, solving root causes instead of using local patches, using generic language instead of client specific. This will ensure that your features are easily contributed even before you begin this process.

  1. List each customization/feature you want to contribute to YMCA Website Services
  • It’s plausible that there are portions of your code that it might not make sense to put into the distribution, either because it’s duplicative to what YMCA Website Services already has, or it might be cost prohibitive to decouple it from your site for back-porting.
  • In the early days of YMCA Website Services, we were less stringent on this step. As long as there was no security or technical risk we accepted any contribution into YMCA Website Services. This led to some problems such as having two nearly identical paragraph types called Blog Post and News Post. These were contributed by two different associations. This caused significant confusion until we resolved the issue with the launch YMCA Website Services 2.0 where we deprecated some of this functionality.
  • You can start this process by taking an inventory of all your customizations that you feel would be good to backport into the distribution.
  • The end deliverable of this step is a list of each independent feature you think it makes sense to contribute.
  1. Your Prioritization
  • Rather than taking a ‘big bang’ approach of decoupling and back-porting all your features into YMCA Website Services, it is a better practice to take a bite-size approach, doing one feature at a time . This is because it can be cost and time intensive and expensive to decouple and backport your code into the distribution if you do it all at once.
  • As a guide, YMCA Website Services uses the following prioritization method: Demand for feature (1 to 3 with 1 being high), Impact/Benefit to Ys and visitors (1 to 3 with 1 being high), Effort to build/maintain (1 to 5 with 1 being extra low and 5 being extra high). The sum of these gives us a ‘score’ for each feature which helps us prioritize.
  • This will also help you decide how much, or little, of your back-porting you want to fund as you’ll be able to get a clear feature-by-feature time estimate for the work required.
  • The end deliverable will be a prioritized list of the features that you want to contribute.
  1. Share your prioritized list with YMCA Website Services, and align roadmaps before spending money and time on decoupling
  • There might be things the YMCA Website Services core team is already working on that are similar and would be finished before your decoupling would be complete, thus it would not be the best use of your funds to decouple/backport that feature
  • There may be information the YMCA Website Services team has based on talks with other Ys that influence your demand/impact scores and thus your prioritization
  • We might have technical knowledge that influences your effort scores as well
  • This is when timelines will start to emerge on when your code would be available in the distribution.
  1. Decoupling
  • Your developers and the YMCA Website Services team should align on best practices for code. At a high level, our best practices can be reviewed here: Development FAQ and How we release code
  • When you are ready to begin the decoupling work let us know and we can either talk to you here, on Slack, or even set up a conference call if it would be helpful for you.
  • You would then start the technical/dev work of decoupling the features you wish to contribute back into YMCA Website Services
  • You would test all of your decoupled code to ensure that these features work when no longer reliant on any paid or non-secure technology or partners
  • Deliverable from this step is code that works in a your own dev environment independent of any other Y association specific code/technology
  1. Contributing your code: Pull Requests (PRs)
  • Code gets submitted to YMCA Website Services for review via a process called a Pull Request
  • The YMCA Website Services lead technical architect sees the code, runs it through automated test cases, and provides feedback on any issues detected that may cause problems for other portions of YMCA Website Services code
  • Sometimes the feedback from the YMCA Website Services lead technical architect requires re-work from the original developer making the PR before the code is accepted into the distribution
  1. Release
  • The features contributed from you get scheduled into one of the YMCA Website Services quarterly releases, and we make sure you get ample credit for your contribution.
  • The movement then benefits from your contribution!
  1. Ongoing improvements, maintenance, etc.
  • Over time, you might want to make enhancements to your site due to analytics, or other data inputs from customers and team-members
  • It would be great if you made those same enhancements to the now-decoupled version of your code that exists in YMCA Website Services if you feel it makes sense
  • If you identify any bugs or issues over time on your site that involve code that was contributed to YMCA Website Services, it would be awesome if you fixed that code and contributed the fix via a Pull request (step 5 above)

To be clear, all of the above is only required if you want to get your code into the core YMCA Website Services distribution. You could always take your code as is, ensure any PII or secure information is scrubbed, and post it to your own GitHub repository – however it would be difficult for others to use this code as is if it hasn’t at least been decoupled. If you take this approach please be sure to remove references to OpenY from the code so that the GitHub search engine does not confuse it with core YMCA Website Services. Further, please review the YMCA Website Services license agreement to make sure you are in alignment with GPL and Open Source sharing best practices.

24 - How to develop themes in YMCA Website Services

Working with Themes

Each YMCA Website Services theme was developed independently, either by the YMCA Website Services Core Team or by a partner for one specific Y and then contributed back. You can see demos of each theme on the Sandboxes.

Each theme has its own dependencies and build processes. Please read the steps in each README for details.

Inventory of themes

As of December 2021, themes have been decoupled from the YMCA Website Services profile to independent projects on Drupal.org.

Carnation

Lily

Rose

25 - Important versions for upgrade path

YMCA Website Services development moves quickly and in this document, we flag important versions that should not be skipped while you upgrade your sites.

Determining your upgrade path

For example: If you are on YMCA Website Services 8.1.2 and want to upgrade to YMCA Website Services 8.2.8.5 you should make it in a couple of steps

  1. Upgrade 8.1.2 to 8.1.13.1
  2. Upgrade 8.1.13.1 to 8.2.2.1
  3. Upgrade 8.2.2.1 to 8.2.7.3
  4. Upgrade 8.2.7.3 …

These supplemental documents elaborate on a few specific cases:

Important versions

  • 8.1.13.1 - Optional, when you have a lot of customized code and 8.2.2.1 is failing in most places.

  • 8.2.2.1 - This is a very important step everyone should have. After this version, drush entup stops working. In this version, we finally migrated to the core media subsystem, and before going further it is important to upgrade media by upgrading your site to this version first.

  • 8.2.7.3 - This is a very stable Drupal 8 based YMCA Website Services with a bunch of contrib module updates. This is one of the last Drupal 8 based YMCA Website Services versions before the upgrade to Drupal 9 core. Also, in 8.2.7.0 and 8.2.7.1 we started to introduce multiple version constraints in composer.json to allow developers to choose between the minimum or latest dependency versions. This is for securing the upgrade path as well as adding flexibility for version selection if needed.

  • 9.2.8.0 - Drupal 9 version which must be used in the upgrade path before going to 9.2.8.1+. This version added 9.0-9.1 Drupal Core and disabled deprecated components.

  • 9.2.10.0 - Removed a bunch of unused modules from distribution.

  • 9.2.11.3 - Last Open Y Drupal core 9.3.* release

  • 9.2.11.4 - Technical release of YMCA Website Services ( no diff with 9.2.11.3 )

  • 9.2.13.0 - Pre Drupal 10 release, latest Drupal 9 release. Before going into Layout Builder era it is recommended to uninstall geysir, openy_inline_editing, quickedit, rdf modules.

  • 10.2.14 - Drupal 10|9 release, where you may follow the recommendations below:

    1. Upgrade to the latest Drupal 9 core (using version 10.2.14 of the distribution, released in June 2023).
    2. Upgrade all contrib modules and libraries to their latest Drupal 9-compatible versions (with composer update).
    3. Use drupal-rector, drupal-check, and PHPCS to prepare custom modules and themes for Drupal 10.
    4. Upgrade to Drupal 10 and run regression testing to search for hard-to-find bugs (update drupal/core-* projects in composer.json, then run compuser update).
    5. Upgrade all contrib modules on the Drupal 10 site to their latest versions (composer update).
  • 10.3.0.1 - Drupal 10|9 release, before New Demo Content and Initial Replacement Paragraphs to Blocks for Native Layout Builder Experience

  • 10.3.1 - Drupal 10|9 release, New Demo Content and Initial Replacement Paragraphs to Blocks for Native Layout Builder Experience. In this release we bumped a lot of dependencies to become up to date

  • 10.3.2 - Introduced recurring event support in the Event Content Type which requires an automated migration between date_range and smart_date fields. If possible, update to this version during the upgrade process.

  • 10.3.2.3 - Introduced before 10.1 and 10.2 Drupal core. Also upgraded openy_map.This version ensures we support removed modules pre 10.1 for contrib modules

See Version Constraints practices for YMCA Website Services

Known issues

If you are faced with an issue when composer installs an improper version of drupal/core for the chosen version of YMCA Website Services from the list above, please use this trick in order to downgrade:

composer require drupal/core-recommended:9.5.9

Run the above command where your docroot is. Use the current core version instead of 9.5.9.

26 - Install Solr site search

YMCA Website Services leverages Apache Solr for a few features:

Quick Start / Upgrade path

  • Log in as admin.

  • Go to admin/modules and enable the YMCA Website Services Search API module.

    image

  • Approve the next step for enabling Database Search.

    image

  • Go to the Search API configuration page admin/config/search/search-api.

  • Verify that the “OpenY Database Search” server is enabled.

  • Visit “Search content” index.

    image

TIP: Admins can enable and the Solr search and switch the index between servers.

  • Index content by clicking “Index now”.

    image

  • Go to the homepage and search for any keyword.

    image

  • Verify search results are displayed correctly.

Starting from the YMCA Website Services installer

  • Find the Select search service step displayed during the YMCA Website Services installation.
  • Choose from one of these options during installation:
    • None
      • Nothing happens if the user chooses this option, search modules are displayed after installation.
    • YMCA Website Services Google Custom Search
      • Google Custom Search configuration form is displayed if the user chooses this option.
      • The YMCA Website Services Google Search module is enabled after installation and ready to use.
    • YMCA Website Services Search API
      • Search API backend options are displayed in this case with the following options:
        • Database
          • The YMCA Website Services Search API module is enabled after installation. The database search API server is enabled. The search is ready to use after content indexation.
        • Solr
          • Additional installation step with Solr configuration form is displayed in this case and user can specify all params for Solr connection. The YMCA Website Services Search API module is enabled after installation, Solr search API server is enabled. The search is ready to use after content indexing (if the correct Solr settings were used).

Switch from database search backend to Solr backend

Watch a video tutorial on how to switch an existing site from the database backend to a Solr server. This requires a Solr server to be configured in your environment.

  • Edit the “Solr search” server from the Search API configuration admin/config/search/search-api.
  • Add the configuration information for your Solr server. Refer to Drupal’s Search API Solr project for troubleshooting connection information.
  • Save the server and observe that Search API has successfully connected to your server.
  • Edit the “Search content” index and change the “Server” field to the newly configured “Solr Search” index.
  • Visit the “Search content” index and click “Index now” to re-index the content.

Solr search can be used with Layout Builder, and requires a few extra steps.

Configure Solr to index the new content types

In order for Solr to index the new content types, they need to be added to the index.

  1. Enable the YMCA Website Services Search API (openy_search_api) module if not already enabled.
  2. Go to Admin > Configuration > Search and metadata > Search API, then Edit the Search content index. (/admin/config/search/search-api/index/search_content/edit)
  3. Configure Solr to index the Layout Builder content types:
    • Scroll down, expand Configure the Content datasource, and check the content types that should be indexed for search.
      “Configure the content datasource” options
    • Save the form.
  4. Configure how Solr indexes the Layout Builder content types:
    • From the Search API configuration, open the dropdown for the Search content index and choose Fields.
      The “fields” option in the options dropdown of the Search API configuration
    • To the right of the Rendered HTML output field options, choose Edit.
    • For each newly added content type, switch “Don’t include the rendered item” to the right view mode.
      Choose the view mode for each content type.
      • In general, new Layout Builder specific content types will use the “Default” view mode, while older Layout Builder-compatible content types should use the “Full content” view mode.

        Content typeView mode
        Article (LB)Default
        BranchFull
        Event (LB)Default
        CampFull
        Camp SubpageFull
        FacilityFull
        Landing Page (LB)Default
        ProgramFull
        Program SubcategoryFull
      • Save the page.

  5. Once your changes have been saved, re-index the content to see the changes reflected in search results.

Set up a Layout Builder search page

  1. If you have an existing site, disable the old search page:
    • Go to /search.
    • Remove the URL alias by unchecking Generate automatic URL alias in the sidebar then deleting /search.
    • Uncheck Published and Save to un-publish the page.
  2. Create a new Landing Page (Layout Builder) (node/add/landing_page_lb):
    • Set the Title to “Search”.
    • Ensure Generate automatic URL alias is unchecked in the sidebar and set the alias to /search.
      • If that alias results in an error, you can remove the old one at Admin > Configuration > Search and metadata > URL aliases
    • Check Published then Save and edit layout.
  3. Add a Small Banner to the header with a title for the page, like “Search”.
  4. Add the search results block to the page:
    • In the Body section, Add block, then expand All system block and choose Content search block from the Paragraph Blocks section.
    • Optionally, choose to hide the title or change the number of items to display.
    • Save layout and check your page.
  5. Change the Search API config to use your new page:
    • Go to Admin > YMCA Website Services > Settings > Search API settings (/admin/openy/settings/search-api) and set the Search page id to the node id of your new page.
    • Or, change the config with drush:
      drush cset openy_search_api.settings search_page_id <nid>
      
  6. Test the search box in the Layout Builder page header to ensure the new configuration works as expected.

Legacy Solr Support

The contrib Search API Solr module supports a broad swath of Solr versions, but occasionally old versions are dropped from support in the main module. If, when enabling YMCA Website Services Search API, you encounter errors that your version of Solr is out of date, you may need to enable the Search API Solr Legacy module. As of January 2022, Search API Solr Legacy supports Solr 3.6 through 6.4.

The error message when using an old version of Solr may look something like this:

Notice: Undefined index: 4.x in Drupal\search_api_solr\Controller\SolrConfigSetController->getConfigFiles()

27 - Install SSL certificate

Web Security and YMCA Website Services

As many parties have moved to Encrypt the Web, https sites and SSL certificates have shifted from “nice to have” to necessities.

If you’re running YMCA Website Services on a managed platform you most likely have SSL already configured. If you choose to manage YMCA Website Services on your own, you’ll have to install a certificate.

Let’s Encrypt is “a free, automated, and open certificate authority (CA), run for the public’s benefit. It is a service provided by the Internet Security Research Group (ISRG).” Certbot is “a free, open source software tool for automatically using Let’s Encrypt certificates on manually-administrated websites to enable HTTPS.”

Certbot maintains detailed documentation for installing SSL certificates on a variety of systems. Simply visit Certbot’s instructions wizard and follow the instructions to configure your server.

28 - Installation With Drush

Use drush site-install command.

Basically you use something like this:

drush site-install openy --account-pass=password --db-url="mysql://user:pass@host:3306/db" --root=/var/www/docroot

Complete YMCA Website Services profile preset and YMCA Website Services Rose theme is used in this case.

You can set which preset must be installed by specifying it with openy_configure_profile.preset variable, and theme with openy_theme_select.themevariable e.g.:

drush site-install openy --account-pass=password --db-url="mysql://user:pass@host:3306/db" --root=/var/www/docroot openy_configure_profile.preset=extended openy_theme_select.theme=openy_rose

29 - Module Development

Module content removal

When deleting an entity, where plugins or services of removing module are used, then content removal should be done in the hook_uninstall() of that module. See openy_prgf_camp_menu.install as example.

Creating a new module

When creating a module on Drupal.org, be sure to check the following:

  1. Add all current maintainers.
  2. Edit and add this module template:
<table class="views-view-grid" bgcolor="#d4efcc"><tr><td><h2>🇺🇦</h2></td><td>This module is maintained by Ukrainian developers. Please consider <a href="https://supportukrainenow.org">supporting Ukraine</a> in a fight for their freedom and the safety of Europe.</td></tr></table>

<!-- Edit this section with a short intro to the module -->
This component/module allows you to ... when using the <a href="https://github.com/YCloudYUSA/y_lb">YMCA Layout Builder</a> package.

<!-- Leave this section as is -->

<ul>
    <li>Read our <a href="https://github.com/YCloudYUSA/yusaopeny#installation">instructions for getting started</a>.</li>
    <li><a href="https://ds-docs.y.org/docs/">Search our documentation</a> for assistance.</li>
    <li><a href="https://ds-docs.y.org/community/">Review our Community Resources</a> for more information.</li>
</ul>

<h3 id="project-requirements">Requirements</h3>

This project is meant to be used with the <a href="https://www.drupal.org/project/openy">YMCA's Website Service distribution</a>.

30 - one-click install how-to

This walk-through is outdated and is in the process of being updated. Instead, try:

Installing YMCA Website Services on DigitalOcean droplet

  1. Create Ubuntu 16.04 LTS x64 droplet in area close to your location image

Use 2Gb droplet or more powerful if you need. Do not use 1Gb option - YMCA Website Services will fail on it.

  1. Login to the SSH console of the droplet
  2. Follow the comment from https://github.com/YCloudYUSA/yusaopeny-project/blob/8.1.x/scripts/openyonclickinstall.sh Basically - run a command under root
curl -Ls http://bit.ly/initopeny | bash -s

The command above will run approximately 10 minutes. 4. In the end you should see a message similar to

Open http://127.0.0.1/core/install.php to proceed with OpenY installation.
  1. Open the link from the above message(from your console, not from this document) with your browser and proceed with YMCA Website Services installation.

Enjoy.


In order to install the latest beta release of YMCA Website Services 2.0 change the command on step 3:

curl -Ls http://bit.ly/initopeny | bash -s beta

If you find any issues please post a message to the issue queue https://github.com/YCloudYUSA/yusaopeny/issues

31 - Open Y analytics sunset

Preamble

Back on 28 Jan 2020 Open Y decided to add an anonymous analytics module openy_analytics which was a free opt-in/opt-out solution for the Core team to gather stats from Open Y sites about the frequency of components used.

The idea behind this was to gather data in order to understand the demand for the components in Open Y and use the data to make better decisions.

Recently, the Open Y Core Team decided to sunset this functionality and remove openy_analytics as well as openy_update modules from the Open Y Distribution, as this feature was rarely used. By sunsetting this functionality, we reduced server load from Open Y instances and archive the analytics server.

How to opt-out from analytics subsystem

Visit YMCA Website Services -> Terms and Conditions in your YMCA Website Services site instance and uncheck the Optional Permissions checkbox

image

After submitting this form your site will stop sending anonymous data.

If the checkbox was not enabled just disregard it, you didn’t opt-in earlier.

Deprecation action

Uninstall and deprecation was done in #2537

32 - Participant Agreement

YMCA Website Services PARTICIPATION AGREEMENT

This YMCA Website Services Participation Agreement (this “Agreement”) is between YUSA, and participating YMCA member associations in the United States (“Member Associations”). YUSA has received license rights from the National Council of Young Men’s Christian Associations of the United States of America, an Illinois not-for-profit corporation (“YUSA”) to provide the Platform (as defined below) to you.

The purpose of the YMCA Website Services community is to collectively advance YMCA web and online experiences to better serve the YMCA mission. The terms of this Agreement govern your use of YMCA Website Services’s open-source digital content management system, which facilitates the sharing of YUSA brand-compliant website templates, tools, applications, and related digital assets (“Platform”). The community provides a collaborative environment for individuals to positively interact and participate in the Platform. These guidelines address the standards and expectations of those contributing to and participating in the YMCA Website Services community and are meant to help our YMCA community grow and thrive. Your participation in YMCA Website Services means that you agree to the following guidelines and to the YMCA Website Services Terms of Use.

YMCA BRAND ASSETS

No right is granted by this Agreement to use or license the YUSA brand assets. YMCA brand assets, which include, but are not limited to YMCA trademarks, trade dress, logos and other indicia of origin, are owned and controlled by YUSA. YUSA provides the Platform to you under license from YUSA. Accordingly, neither YUSA nor any Member Association shall, either directly or indirectly, at any time do any act or thing contesting the validity of YUSA’s trademarks or its rights thereto.

Only Member Associations in the United States will have access to use any YUSA brand assets included in YMCA Website Services. All use by Member Associations must be in compliance with YUSA brand standards and guidelines as established by the National Board. YUSA is a third party beneficiary to this Agreement, with the right to enforce each of the terms of this Agreement with respect to YMCA Website Services and you. YMCA Website Services shall send copies of all notices due to you under this Agreement to each of you and YUSA.

BEING A MEMBER OF OUR COMMUNITY

Participation: YMCA Website Services will be at its best if each member participates in the community. There are many different ways you can participate, including through using the platform, presentations, forums, summits, emails, calls, etc. We encourage your active participation to the extent you feel you are able and willing. YUSA may publicly disclose your participation in the project.

Contribution: YMCA Website Services encourages Members to contribute to the enhancement, editing, and building of YMCA Website Services. To ensure valuable contributions to the community, YMCA Website Services encourages Members to stay familiar and up-to-date with the YMCA Website Services roadmap, as well as new features in active development. When you make changes that improve YMCA Website Services features, please contribute those back to the community by ensuring they are re-useable and decoupled.

Collaboration: YMCA Website Services encourages Members to collaborate across the YMCA community to share costs and efforts on building new capabilities.

Transparency: Customizations of code provided by YMCA Website Services for your website will likely increase the initial fees, support, and upgrade costs for your website. When modifying or redistributing code, you must include a notice giving credit to YMCA Website Services for the portion of the YMCA Website Services code you use.

Promotion: YMCA Website Services encourages Members to share their expertise and YMCA Website Services experience to expand its reach and accessibility to experienced and new members alike. There will be many opportunities for members to support YMCA Website Services and its marketing and messaging initiatives.

Reporting Problems

If you believe someone has violated the YMCA Website Services Community Guidelines, or have any questions or concerns, please contact YUSA at https://ymca.org.

33 - Patch YMCA Website Services

Here you can find instructions how you can patch YMCA Website Services distribution used on your project.

When you need to patch YMCA Website Services

  • In case you found a bug and prepared a patch for YMCA Website Services on github.
  • In case you developed a new feature that will be good to have in YMCA Website Services and created Pull Request to YMCA Website Services repository
  • In case you want to add a feature that added to YMCA Website Services but not included yet to YMCA Website Services release.

How to patch YMCA Website Services via composer?

If you followed instructions docs/Development/Start new YMCA Website Services project and you have configured composer.json you need just to do a few simple steps:

  1. Build a link to a patch using pull request ID

    https://patch-diff.githubusercontent.com/raw/YCloudYUSA/yusaopeny/pull/XXX.patch
    

Where XXX is a number of pull request you want to use.

  1. Add a new section patches to the section extra and add a patch to YMCA Website Services repository, as on this example:

    "extra": {
        "installer-paths": {
          ...
        },
        "enable-patching": true,
        "patches": {
            "YCloudYUSA/yusaopeny": {
                "Patch description": "https://patch-diff.githubusercontent.com/raw/YCloudYUSA/yusaopeny/pull/XXX.patch"
            }
        }
    }
    
  2. After adding a patch execute command composer update

  3. Verify you can see added changes in YMCA Website Services

  4. Enjoy!

34 - Profile custom configuration

The distribution supplements the Drupal install process with a number of custom additions.

There are plenty of YAML configuration files at the root of the profile. Some of them are standard Drupal configuration and others are YMCA Website Services specific.

Basic .yml files

The following ones are very common and can be found in many Drupal modules:

  • openy.info.yml ( documentation) - defines YMCA Website Services as a profile and defines its name and dependencies
  • openy.libraries.yml ( documentation) - defines global YMCA Website Services drupal asset libraries
  • openy.permissions.yml - defines global YMCA Website Services permissions
  • openy.services.yml ( documentation) - if you are introducing a service that is needed by all (or the majority of) YMCA Website Services modules add it here and store the service class file in the openy/src directory

YMCA Website Services specific .yml files

There are also a few configurations related to the YMCA Website Services installation process and the YMCA Website Services package system:

  • openy.installation_types.yml
  • openy.themes.yml
  • openy.packages.yml

YMCA Website Services packages

The YMCA Website Services package system introduces a new level of abstraction, shifting from the Drupal standard module level to packages. Packages represent complete YMCA Website Services features, which could include multiple modules. A package is a declaration of a group of several modules. You can enable and disable a package, which means the whole set of the associated Drupal modules are enabled or disabled.

This approach provides a convenient way of managing YMCA Website Services features.

The YMCA Website Services system module provides a page where the enabled and available packages are listed and can be installed/uninstalled. See the YMCA Website Services Extend page (at /admin/openy/extend).

YMCA Website Services Installation types

When an YMCA Website Services site is installed there is also another abstraction level - the installation type - which groups packages.

The hierarchy is as follows:

  • installation type
    • package
      • module
      • module
    • package
      • module
      • module
      • module
    • package
      • module
  • installation type
    • package
      • module

openy.installation_types.yml

openy.installation_types.yml defines the high-level presets available during website installation.

File structure:

standard:
  name: Standard
  packages:
    - alerts
    - editorial
    - news
    - seo
    - webform

extended:
  name: Extended
  packages:
    - alerts
    - analytics
    - ...

complete:
  name: Complete/Developer
  hidden: true
  packages:
    - activenet
    - ...

Each installation type has a machine name which is a key of the top-level items.

Properties of installation types:

  • name (required) - a human-friendly name of the installation type
  • packages (required) - a list of YMCA Website Services packages that are associated with the installation type. The packages are listed when a website is installed via the web-interface
  • hidden (optional) - if the installation type must be hidden when a website is installed via the web interface

If an YMCA Website Services site is installed using the web interface there is a step where the installation type can be selected.

If an YMCA Website Services site is installed using Drush then the installation type can be specified by an optional argument for the drush site-install command ( Installation with Drush):

  drush site-install openy \
     --db-url="mysql://user:pass@host:3306/db" \
     --root=/docroot \
     openy_configure_profile.preset=extended

openy.packages.yml

Packages are defined in openy.packages.yml. This file is placed in the root of the profile, it’s automatically detected and used by the YMCA Website Services installation process.

File structure

blog:
  name: 'Blog'
  description: "Blog package provides a set of modules to maintain and create different blog post listings."
  help: '<p>Using Blog package you can create and maintain blog posts and create flexible listings of blog posts. Watch a video below to learn more about blog anatomy.</p>
  <iframe width="560" height="315"
               src="https://www.youtube.com/embed/Vg1fy29DhdQ"
               frameborder="0" allow="autoplay; encrypted-media"
               allowfullscreen></iframe>'
  modules:
    - openy_node_blog
    - openy_prgf_blog_listing
    - openy_prgf_featured_blogs
    - openy_prgf_blog_branch
    - openy_prgf_blog_camp
    - openy_prgf_blog_latest
    - openy_txnm_blog_category

camps:
  name: 'Camps'
  description: "Camps package provides a set of modules to maintain camps and add them to the location finder page."
  help: '<p>Using Camps package you can create and maintain Camps and extend location finder page to include them.</p>'
  modules:
    - openy_prgf_camp_menu
    - openy_loc_camp

Each package has a machine name which is a key of the top-level items.

Properties of packages:

  • name (required) - a human-friendly name of the package.
  • description (required) - a short description of the package features to show up on the YMCA Website Services Extend page.
  • help (required) - an HTML markup for the installation via web interface. It contains a help message that pops up when the package name is clicked on the Select installation type step.
  • modules (required) - a list of Drupal modules that are associated with the package. When the package is installed/uninstalled the associated modules are installed/uninstalled respectively. When a website is installed via web interface all the available packages are listed there but split into two groups - the ones that are to be installed (associated with the selected package) and all the rest.

openy.theme.yml

The file defines which YMCA Website Services themes are available for installation when a website is being installed.

If an YMCA Website Services site is installed using Drush then the theme can be specified by an optional argument for the drush site-install command ( Installation with Drush):

  drush site-install openy \
    --db-url="mysql://user:pass@host:3306/db" \
    --root=/docroot \
    openy_configure_profile.preset=extended \
    openy_theme_select.theme=openy_rose

35 - Program Event Framework

A robust set of content types and syncer modules that build interactive tools to help members find and book activities.

“Program Event Framework” refers to the entire ecosystem of content and modules in YMCA Website Services that work together to build Activity Finder, Group Schedules, and more.

Content Types

These provide the containers for PEF content in Drupal:

Syncers

These provide integrations to pull content from external systems into the content types:

Displays

These display the content for users to discover:

Data model

The network of data structures in PEF can be confusing. Here’s how it all works

---
title: PEF Relationships
---
erDiagram
    program {
        entityRefTerm field_program_color
        paragraph field_content
        paragraph field_header_content
        paragraph field_sidebar_content
        textFormattedLong field_program_description
        entityRefMedia field_program_icon
        entityRefMedia field_program_image
        layout layout_builder__layout
        meta field_meta_tags
        bool field_use_layout_builder
    }
    program_subcategory {
        paragraph field_bottom_content
        entityRefTerm field_category_color
        paragraph field_content
        paragraph field_sidebar_content
        textFormattedLong field_category_description
        paragraph field_header_content
        entityRefMedia field_category_image
        layout layout_builder__layout
        meta field_meta_tags
        entityRefProgram field_category_program
        bool field_use_layout_builder
    }
    program_subcategory }|--|| program : field_category_program
    activity {
        textFormattedLong field_activity_description
        entityRefProgSub field_activity_category
    }
    activity }o--|| program_subcategory : field_activity_category
    class {
        entityRefActivity field_class_activity
        paragraph field_bottom_content
        paragraph field_content
        textFormattedLong field_class_description
        paragraph field_header_content
        meta field_meta_tags
        paragraph field_sidebar_content
    }
    class }o--|| activity : field_class_activity
    session {
        listText field_activity_type
        entityRefClass field_session_class
        textFormattedLong field_session_description
        dateRange field_session_exclusions
        listText field_session_gender
        numberInt field_availability
        bool field_session_in_mbrsh
        textPlain field_session_instructor
        entityRefLoc field_session_location
        numberInt field_session_max_age
        listText field_session_max_grade
        numberDec field_session_mbr_price
        numberInt field_session_min_age
        listText field_session_min_grade
        numberDec field_session_nmbr_price
        bool field_session_online
        entityRef field_session_plocation
        numberInt field_productid
        link field_session_reg_link
        textPlain field_session_room
        paragraph field_session_time
        numberInt field_wait_list_availability
    }
    session }|--|| class : field_session_class
    session ||--o{ session_time_paragraph : field_session_type
    session_time_paragraph {
        dateRange field_session_time_date
        listText field_session_time_days
        textPlain field_session_time_override
    }
    branch {

    }
    camp {

    }
    facility {

    }
    session }o--|| branch : field_session_location
    session }o--|| camp : field_session_location
    session }o--|| facility : field_session_location
    session }o--|| facility : field_session_plocation

More information on how this data gets out into each display will be coming soon.

35.1 - Activity Finder

Provides an interactive tool to help members find and book activities.

YCloudYUSA/yusaopeny_activity_finder is bundled as a “decoupled application” that ships with the YMCA Website Services distribution.

Requirements

This module requires the following modules:

  • openy_map (For pulling the list of location-related content types.)

This module also requires one of the following to store data:

  • A Solr server (preferably a server or index per-environment).
  • A subscription with access to the Daxko API.

Activity Finder is most often used with a syncer to pull data from an external source.

Installation

Activity Finder version 4 is the current major version. Prior to 9.2.10.0, the distribution required ^3.1 || ^4.0, allowing you to choose which version you want to use depending on the project requirements.

Deprecations

Outdated implementations are not removed immediately, allowing you to update your projects and migrate to new components without breaking your site. They are marked with [deprecated] notices in the next version and are planned to be removed in the future releases.

New Projects

Install as you would normally install a contributed Drupal module. For further information, see Installing Drupal Modules.

New projects should enable:

  • Activity Finder (openy_activity_finder)

then choose one or both of the front ends:

  • LB (Layout Builder) Activity Finder (lb_activity_finder)
  • Open Y Paragraph Activity Finder (openy_prgf_activity_finder_4)

and finally enable one of these data stores:

  • Search API Solr (search_api_solr)
  • Daxko API v2 integration (openy_daxko2)

Existing Projects

You have a choice of either staying on the same version you use or to update to the next version. It depends on your project requirements and customizations. We recommend updating to the latest release if you have resources for it.

Update from version 3.x to version 4.x

Activity Finder is a complex functionality, it connects together many different pieces and might require additional steps to make it working. The list of actions below outlines the major steps to get Activity Finder updated to version 4.

  • Update the codebase using the composer command: composer require ycloudyusa/yusaopeny_activity_finder:&#34;^4.0&#34;
  • Run database updates drush -y updb.
    • Verify there were no errors and updates went fine.
  • Install the new "Open Y Paragraph Activity Finder" (openy_prgf_activity_finder_4): drush en openy_prgf_activity_finder_4
  • Create or update a existing Landing Page with Activity Finder.
  • Add Activity Finder paragraph (replace the deprecated paragraph), configure it and save the page.
    • Verify the page and Activity Finder functionality is working fine
  • The previous version of Activity Finder used 2 landing pages with 2 paragraph types - one for wizard and another one for results. Find and remove these pages.
  • Uninstall "OpenY Paragraph Activity Finder" (openy_prgf_activity_finder).
  • Uninstall "OpenY Paragraph Activity Finder Search" (openy_paragraph_activity_finder_search).

Configuration

Set up Solr

In order to install Solr - check the documentation on Drupal.org.

After enabling the above modules you should visit /admin/config/search/search-api and obtain config.zip from preconfigured by Open Y Solr Server setup image

This configuration should be installed on your Solr server as an independent core. it should be extracted to the conf directory of a solr core

image

Once it is done - ensure the name of your core from core.properties file added to Solr Server config in Open Y image

Solr server configuration could be found in Dropdown at /admin/config/search/search-api image image

If you prefer drush configuration you may use commands below, just replace SOLR_CORE_IS_HERE with real core name

drush cset -y search_api.server.solr backend_config.connector_config.host 127.0.0.1 -y
drush cset -y search_api.server.solr backend_config.connector_config.core ${SOLR_CORE_IS_HERE} -y
drush search-api:reset-tracker
drush search-api:index

Once this is done you should see Solr Server as Index as Enabled on a /admin/config/search/search-api

If you installed Open Y with Demo content now it is time to create a Landing Page with the Activity Finder v4 component on it.

In Open Y we have a specially created module which can this for you

Enable openy_prgf_af4_demo by drush command

drush en openy_prgf_af4_demo

and you’d get /activity-finder-v4 Landing Page created automatically which should look like image

when you visited it. By visiting /activity-finder-v4?step=results or clicking on suggested buttons you should see results, activities with filters and all other functionality, shipped with Activity Finder v4 For the Demo content from OpenY, it should look like image

Set Trusted Redirect Host patterns

Activity Finder has a feature to track redirects to 3rd party systems. In order to control the URLs to redirect to you should use the trusted host patterns. This feature works similar to Drupal core trusted_host_patterns setting.

Example - add this section to the settings.php:

// Trusted hosts to redirect to for Activity Finder.
$settings[&#39;activity_finder_trusted_redirect_host_patterns&#39;] = [
  &#39;^apm\.activecommunities\.com$&#39;,
];

It is also recommended to disallow these paths in robots.txt:

# Activity Finder redirects
Disallow: /af/register-redirect/
Disallow: /index.php/af/register-redirect/

Add the Activity Finder block

See the full documentation on Activity Finder for information on how to add the block to your page and block options.

Troubleshooting & FAQ

To demo Activity Finder, see these sandboxes:

Limitations with using Daxko backend

When using the Daxko backend. Developers should be aware of these limitations:

  • We can't use home branch functionality on start screen.
  • We have to use Legacy mode.
  • We can't display count of result for each age on the age's wizard step.
  • We can't display count of available spots for each activity, before user click by activity details.
  • Limited pager on results page. We can display only previous and next page link and can't display count of pages.

How to override processResults in Activity Finder

See openy_activity_finder.api.php

/**
 * Implements hook_activity_finder_program_process_results_alter().
 */
function custom_module_activity_finder_program_process_results_alter(&amp;$data, NodeInterface $entity) {
  // Get formatted session data from some custom service.
  $formatted_session = \Drupal::service(&#39;ymca_class_page.data_provider&#39;)
    -&gt;formatSessions([$entity], FALSE);
  $formatted_session = reset($formatted_session);

  // Fix pricing according to YMCA price customization.
  $data[&#39;price&#39;] = &#39;&#39;;
  if (!empty($formatted_session[&#39;prices&#39;])) {
    foreach ($formatted_session[&#39;prices&#39;] as $price) {
      $data[&#39;price&#39;] .= implode(&#39; &#39;, $price) . &#39;&lt;br&gt;&#39;;
    }
  }

  // Fix availability and registration according to YMCA customization.
  $messages = [
    &#39;begun&#39; =&gt; t(&#39;This class has begun.&#39;),
    &#39;will_open&#39; =&gt; t(&#39;Registration for this class opens shortly. Please check back.&#39;),
    &#39;inperson&#39; =&gt; t(&#39;Online registration is closed. Visit a YMCA branch to register.&#39;),
    &#39;included_in_membership&#39; =&gt; t(&#39;Included in Membership&#39;),
  ];

  if (isset($messages[$formatted_session[&#39;reg_state&#39;]])) {
    $data[&#39;availability_note&#39;] = $messages[$formatted_session[&#39;reg_state&#39;]];
  }
}

How to add external functionality to analytics event

See openy_af4_vue_app/main.js

// Listen to a custom event to pass events in Google Analytics.
document.addEventListener(&#39;openy_activity_finder_event&#39;, (e) =&gt; {
  const { action, label, value, category } = e.detail

  if (window.gtag) {
    window.gtag(&#39;event&#39;, action, {
      event_category: category,
      event_label: label,
      value: value
    })
  } else if (window.ga) {
    window.ga(&#39;send&#39;, &#39;event&#39;, category, action, label, value)
  }
})

Example of custom event

document.addEventListener(&#39;openy_activity_finder_event&#39;, (e) =&gt; {
  const { action, label, value, category } = e.detail // Properties you can use for analitics.
  ...
  { your_functionality }
  ...
})

Add custom component in between of results

it allows flexibility in terms of results rendering for the developer:

          &lt;ResultsList
            :results=&#34;data.table&#34;
            :ages=&#34;ages&#34;
            :selected-ages=&#34;selectedAges&#34;
            :legacy-mode=&#34;legacyMode&#34;
            :disable-spots-available=&#34;disableSpotsAvailable&#34;
            @showActivityDetailsModal=&#34;showActivityDetailsModal($event)&#34;
          /&gt;

can be changed to this:

          &lt;ResultsList
            :results=&#34;data.table.slice(0, 2)&#34;
            :ages=&#34;ages&#34;
            :selected-ages=&#34;selectedAges&#34;
            :legacy-mode=&#34;legacyMode&#34;
            :disable-spots-available=&#34;disableSpotsAvailable&#34;
            @showActivityDetailsModal=&#34;showActivityDetailsModal($event)&#34;
          /&gt;
          &lt;YGBWAds /&gt;
          &lt;ResultsList
            :results=&#34;data.table.slice(2)&#34;
            :ages=&#34;ages&#34;
            :selected-ages=&#34;selectedAges&#34;
            :legacy-mode=&#34;legacyMode&#34;
            :disable-spots-available=&#34;disableSpotsAvailable&#34;
            @showActivityDetailsModal=&#34;showActivityDetailsModal($event)&#34;
          /&gt;

where YGBWAds is custom component to render custom content in between the results. See https://github.com/ymcatwincities/openy_activity_finder/pull/148

35.1.1 - Adding Activity Finder to your site

Both v4 and v3 could live together as independent programs on your site, and they will show the same data from the Program Event Framework of Open Y image

On the screenshot above you can see Open Y components in a list for both Activity Finder v3 and v4

In order to create v3 Activity Finder application you need to create 2 landing pages, referencing each other, one with Activity Finder [deprecated], another one with Activity Finder Search [deprecated] image See

image See

In order to create v4 Activity Finder application, you need to create 1 landing page, with the Activity Finder component on it image See sandbox

35.1.2 - Bootstrap version support for Activity Finder

In the Carnation theme we use bootstrap v 4.6 and for this case we have a special option Bootstrap version in settings form for Activity Finder v4 (/admin/openy/settings/activity-finder)

image

Rose and Lily themes are using Bootstrap v3, Carnation theme is on Bootstrap v4 And when we set it to 4 then the AF4 result page looks good for the tablet screen on Carnation image image

35.1.3 - Configuring Solr for Activity Finder

In order to install Open Y and Activity Finder v4 you need to run command

composer create-project ymcatwincities/openy-project build --no-interaction --prefer-dist

Which will pull Open Y on Drupal stable version with Activity Finder v4 latest stable version Then you should proceed with a regular installation with Demo content enabled as described in our tutorials. It’s better to setup Extended or Custom( only via drush ) in order to skip a bunch of manual steps

When you have YMCA Website Services (former Open Y) installed, list of the command you need to run in order to enable Activity Finder v4

# Solr 8.8.1, Activity Finder v4
drush en -y search_api_solr_legacy openy_prgf_activity_finder_4 || true
drush en -dvy openy_prgf_af4_demo || true

After enabling the above modules you should visit /admin/config/search/search-api and obtain config.zip from preconfigured by Open Y Solr Server setup image

Hint: Open Y module’s infrastructure supports SOLR versions 8 up to the latest 8.8.1 as well. Activity Finder is tested against Solr 8.8.1. In order to install Solr - check the documentation on Drupal.org. Solr versions prior 7.7 are End of Life, Open Y team is working on upgrading support for decent versions of Solr.

This configuration should be installed on your Solr 8.8.1 server as a independent core. it should be extracted to conf directory of a solr core

image

Once it is done - ensure the name of your core from core.properties file added to Solr Server config in Open Y image

Solr server configuration could be found in Dropdown at /admin/config/search/search-api image image

If you prefer drush configuration you may use commands below, just replace SOLR_CORE_IS_HERE with real core name

# Solr 8.8.1, Activity Finder v4

drush cset -y search_api.server.solr backend_config.connector_config.host 127.0.0.1 -y || true
drush cset -y search_api.server.solr backend_config.connector_config.core ${SOLR_CORE_IS_HERE} -y
drush cset -y search_api.server.solr backend_config.connector_config.solr_version 8 -y
drush search-api-mark-all || true
drush sapi-i || true

Once you done this you should see Solr Server as Index as Enabled on a /admin/config/search/search-api

If you installed Open Y with Demo content now it is time to create a Landing Page with the Activity Finder v4 component on it. In Open Y we have a specially created module which can this for you Enable openy_prgf_af4_demo by drush command

# Solr 8.8.1, Activity Finder v4
drush en -dvy openy_prgf_af4_demo || true

and you’d get /activity-finder-v4 Landing Page created automatically which should look like image

when you visited it. By visiting /activity-finder-v4?step=results or clicking on suggested buttons you should see results, activities with filters and all other functionality, shipped with Activity Finder v4 For the Demo content from OpenY, it should look like image See sandboxes

Activity Finder v3 also installed when you chose Custom Installation with Demo content and is part of demo content. Could be accessed via /activity-finder url See sandboxes

Development SOLR 8 installation

Solr Docker readme https://github.com/docker-solr/docker-solr/blob/master/README.md

mkdir solr8
sudo chown 8983:8983 solr8
docker run -v "$PWD/solr8:/var/solr" -p 8984:8983 --name d9_sandbox_rose_custom solr solr-precreate d9_sandbox_rose_custom
# stop docker and remove created container
# unpack solr_8.x_config.zip into data/d9_sandbox_rose_custom/conf/

docker run -v "$PWD/solr8:/var/solr" -p 8984:8983 --name d9_sandbox_rose_custom solr solr-precreate d9_sandbox_rose_custom

Configure Open Y to change Solr version to 8.x Change address port to 8984

Rebuild index information Reindex Check Activity Finder v4 is working now

35.2 - PEF Schedules

The “PEF Schedules” module allows Ys to create and manage schedules with a simple, calendar-based view.

YCloudYUSA/y_pef_schedule

The Y PEF Schedule module provides a calendar functionality for scheduling events. It includes a Vue.js component, fullcalendar-app, to display and interact with the calendar.

Requirements

Installation

composer require ycloudyusa/y_pef_schedule
drush en y_pef_schedule lb_simple_schedule
  1. Install as you would normally install a contributed Drupal module. For further information, see Installing Drupal Modules.
  2. Enable the module by navigating to Admin > Extend (/admin/modules) in your Drupal admin interface, then enabling "Y PEF Schedules Admin tool" and "LB Simple Schedule".

Configuration

  1. Configure the calendar settings at Admin > YMCA Website Services > Settings > Schedules calendar settings (/admin/openy/settings/schedules-calendar)
  2. Go to Admin > Content > Schedules Calendar (/admin/openy/branch-schedules) and select a branch.

After choosing a branch, you can view the calendar. The calendar features include:

  1. Viewing events in weekly or daily format.
  2. Viewing the main information of the event (by clicking on the event).
  3. Creating a new event (using the Session Content Type).
  4. Updating existing events.
  5. Downloading the schedule in PDF format.
  6. Filtering results by categories.

Showing the calendar on a page

Once you have added sessions to a calendar, you can add the calendar block to a Layout Builder page to display on the site. Ensure the "LB Simple Schedule" is enabled first.

  1. Edit the Layout of a Layout Builder page (Branch, Landing Page, etc).
  2. Create or find a section, then Add Block.
  3. Choose Add custom/content block then Simple Schedule.
  4. Add a Title and choose a Branch to populate the calendar.
  5. Save the block and the page.

Customization

A few options are available for advanced customization of the calendar.

Retrieving Events

The module provides controllers to handle AJAX requests for fetching events. To create a custom request, use the following route in your JavaScript code:

axios.get(&#39;/fullcalendar-api/get-event-data-date-range/{location}/{start}/{end}/{category}&#39;)
  .then(response =&gt; {
    const events = response.data;
    // Process the received events as needed
  })
  .catch(error =&gt; {
    console.error(&#39;Error fetching events:&#39;, error);
  });

Replace {location}, {start}, {end}, and {category} with the appropriate values.

Creating Events

The fullcalendar-app component allows users to create events interactively. When a date is clicked, a modal form is displayed for users to enter event details such as title, category, time, and date.

To customize the form or extend the functionality, refer to the Vue.js component documentation and customize the handleDateClick and createEvent methods in the fullcalendar-app component.

Troubleshooting

Known issues

  1. After creating a series of events, it is created, but only one event is displayed in the calendar, the page must be refreshed to see the correct data
  2. The color is fixed to the session and not to the category
  3. PDF format is A3

35.3 - Traction Rec Integration

Instructions for configuring and importing data from Traction Rec into the Program Event Framework

Via Traction Rec Integration (ycloudyusa/openy_traction_rec)

This module provides YMCA Website Services integration with the Traction Rec CRM.

Installation

Require this module:

composer require ycloudyusa/openy_traction_rec

Then enable the necessary modules and submodules:

drush en openy_traction_rec openy_traction_rec_import openy_tr_activity_finder

Usage

The main module itself provides only API that helps fetch data from TractionRec. More specific functionality is provided in submodules:

  • YMCA Website Services Traction Rec: PEF import provides PEF migrations.
  • YMCA Website Services Traction Rec: Activity Finder extends YMCA Website Services Activity Finder with the new fields and logic.

See modules/openy_traction_rec_import/README.md for details on how to import content once configuration is complete.

Configuration

Create a Connected App in Salesforce

  1. Create a new private key and X509 certificate, customizing the subj options in the command to suit your organization. (See the manual for openssl-req to understand the options here.)
    openssl req -x509 -noenc -sha256 -days 365 \
     -keyout traction_rec.key \
     -out traction_rec.crt \
     -subj &#34;/C=US/ST=Illinois/L=Chicago/O=My YMCA/OU=Org/emailAddress=youremail@example.com&#34;
    
    • The email address in the certificate does not need to match the email on the Connected App.
    • The certificate must be renewed yearly (or after the set number of --days). We recommend you set a reminder in order to prevent unwanted failures.
  2. In Salesforce > Setup > App Manager, create a New Connected App.
    • Set a Name and Email.
      • The Contact Email is not used for authentication.
    • Check Enable OAuth Settings
      • Set the callback url as the base URL of your site
      • Check Use digital signatures and upload the X509 certificate (.crt) created above.
      • Ensure the app has the following Selected OAuth Scopes
        • Full access (full)
        • Manage user data via APIs (api)
        • Manage user data via Web browsers (web)
        • Perform requests at any time (refresh_token, offline_access)
      • Check these options:
        • Require Proof Key for Code Exchange (PKCE) Extension for Supported Authorization Flows
        • Issue JSON Web Token (JWT)-based access tokens for named users
      • Uncheck all other options in the OAuth section.
    • Save the Connected App
  3. Once the app is saved, you will need to get the Consumer Details:
    • In the "My Connected App" screen that appears once you save (or via Setup > App Manager), click Manage Consumer Details.
    • Save the Consumer Key and Consumer Secret for the next step.
  4. Create a Profile OR Permission Set to assign permissions to your app. We recommend using a Permission Set as those are the option recommended by Salesforce.
    1. Your Traction Rec support team should be able to deploy the Traction Rec Activity Finder Permission Set from their dev1 instance. If this Permission Set is deployed, proceed straight to the User creation step. To create a Permission Set from scratch:
    • Setup > Users > Permission Sets > New
    • Fill in the Label as you wish, and leave License as --None--
    • In the new Permission Set, open Object Settings.
    • In the very long list of Object Settings, do the following for each of the 10 Objects listed below:
      • Find the object and click to open it. In the configuration screen for each Object:
        • Under Object Permissions, mark Read as Enabled.
        • Under Field Permissions, mark Read Access on the header field to provide access to all fields.
      • Save the Object Settings and search for the next one.
    • Finally, review the summary of access permissions and ensure Read access is provided for each of the necessary objects.
    1. Create a Profile:
      • You must do this before creating a user.
      • Setup > Users > Profiles > New
      • When asked what Existing Profile to clone from, select Standard User or Standard Platform User. Be sure to note the User License connected to the target profile.
      • In the very large configuration screen, click Edit, then:
      • Save those changes.
  5. Create a new User with the new Profile or Permission Set:
  • Setup > Users > New User
    • User License - The option under which you created the Profile in the previous step, or Salesforce.
    • Email - A working email that you will use to receive login verifications.
    • Username - This is not your email and must be unique across all Salesforce Organizations. This is the name that will be used in the Drupal connection below. If you enter a preexisting username, you will receive this error: > Error: Duplicate Username. > The username already exists in this or another Salesforce organization. Usernames must be unique across all Salesforce organizations. To resolve, use a different username (it doesn't need to match the user's email address).
    • Assign the User to the Profile you created above, or a Permission Set that has the necessary permissions.
      • Under Permission Set Assignments, click Edit Assignments
      • Find the Permission Set you created in the prior step, select it, click Add, then Save.
  1. Confirm your Connected App, Profile, and User are connected:
    • Go to Setup > Apps > Connected Apps > Manage Connected Apps and choose your new app. Assign the Profile or Permission Set that contains your new user if it does not already show under the relevant section.
      • Click Manage Profiles or Manage Permission Sets
      • Search for your Profile or Permission Set and Save.
    • In the Connect App Detail, click Edit Policies:
      • Under OAuth Policies > Permitted Users choose Admin approved users are pre-authorized.
      • Check Issue JSON Web Token (JWT)-based access tokens.
      • Save the Connected App details.

> When the process is complete, you should have the following relationships between the User, Permission Set OR Profile, and Connected App: > - the API User should be assigned the Permission Set OR Profile. > - the Connected App should be assigned the same Permission Set OR Profile.

Review all of these steps carefully. Missing any of them can result in an inability to query the API.

Salesforce permissions

The Salesforce integration Permission Set OR Profile should have read access to all fields in the following objects:

  • Course Options
  • Courses
  • Course Session Options
  • Course Sessions
  • Locations
  • Products and Discounts
  • Program Categories
  • Program Category Tags
  • Programs
  • Sessions

If using a Profile, it should also have the following Systems Permissions:

  • Apex REST Services
  • View Restriction and Scoping Rules
  • Update Consent Preferences Using REST API

Configure the connection in Drupal

  1. Go to Admin > Configuration > System > Keys (/admin/config/system/keys) and create a new key to store the private key created above.
    • Add key
    • Add a Key name and Description
    • Choose Key Type: "TractionRec JWT Private Key"
    • Choose the Key provider depending on your configuration. See Managing Keys for details.
    • Configure the chosen provider then Save the key.
  2. Go to Admin > YMCA Website Services > Integrations > Traction Rec > Traction Rec auth settings (/admin/openy/integrations/traction-rec/auth) to configure the keys & secrets provided by Traction Rec.
    • Add the Consumer key and Consumer Secret from Manage Consumer Details in Salesforce.
    • Add the User connected to the Connected App.
      • This is the Username of the User, not the Contact email.
    • Enter a Login URL.
      • This will most likely be https://login.salesforce.com
    • Set the Services base URL and REST API Base URL as per their descriptions.
      • Ensure the REST API Base URL responds to curl -I with a 200 response. Replace URLs like *.lightning.force.com with *.my.salesforce.com because the lightning url may result in a redirect, which will cause an authentication error, like ([@&#34;message&#34;:&#34;Session expired or invalid&#34;,&#34;errorCode&#34;:&#34;INVALID_SESSION_ID&#34;]).
    • Set the Community URL based on the publicly accessible registration links.
      • This may be something like https://my-ymca.my.site.com
      • The URL can be found in Salesforce under Setup > Digital Experiences > All Sites.
    • Choose the key as configured above.

Mapping

The TractionRec importer pulls data from many Traction Rec Objects (see TractionRec.php for the full queries):

Object Mapping

The fetcher outputs these files:

  • classes.json - from Courses
    • Maps to both Activities and Classes. Since TREC does not have this distinction, information in the resulting Activities and Classes in Drupal is duplicated.
  • locations.json - from Locations
    • This file is unused, but Locations map to Location via the Session import.
  • program_categories.json - from Program Category Tags
    • Maps to Program.
  • programs.json - from Programs
    • Maps to Program Subcategory.
  • sessions.json - from Course Options
    • Maps to Session.

Note: Traction Rec's labels for "Programs" and their child groupings are different:

  • Traction Rec: "Program Category" is the parent of "Program".
  • Drupal: "Program" is the parent of "Program Subcategory".

Mapping to Drupal fields

Those files are then imported into Drupal content via importers (in config items that start with migrate_plus.). The import goes as follows:

> - Drupal Content Type (bundle) > - Salesforce/TractionRec source fieldDrupal destination field

  • Program - from programs.json / TREC Program Categories
    • Id → id
    • Name → Title
    • Available → Published (status)
  • Program Subcategory - from program_categories.json/ TREC Programs
    • Id → id
    • Name → Title
    • Program → Program (field_category_program) via a lookup to the Programs import
    • Available → Published (status)
  • Activity - from classes.json / TREC Courses
    • Id → id
    • Name → Title
    • Program/Id → Program Subcategory (field_activity_category) via a lookup to the Program Subcategory import
    • Available → Published (status)
  • Class - from classes.json / TREC Courses
    • Id → id
      • The Class Id will also be used to set the Activity (field_class_activity)
    • Name → Title
    • Program/Id → ignored
    • Description/Rich Description → Description (field_class_description)
      • If a Rich Description is set, it will be used, otherwise the Description field will be used.
    • Available → Published (status)
  • Session - from sessions.json / TREC Sessions
    • Course_Option/Name → Title
    • Course_Option/ID → id
      • Also used to generate the Registration link URL using the Community URL set in Traction Rec auth settings (/admin/openy/integrations/traction-rec/auth).
    • Course_Session/Course/Id → Class
    • Course_Session/Course/Name → Course
    • Course_Session/Course/Description & Rich_Description → Description (field_class_description)
      • If a Rich Description is set, it will be used, otherwise the Description field will be used.
    • Course_Option/Start_Date → Session Time > Start date
    • Course_Option/Start_Time → Session Time > Start time
    • Course_Option/End_Date → Session Time > End date
    • Course_Option/End_Time → Session Time > End time
    • Course_Option/Day_of_Week → Session Time > Days
    • Course_Option/Age_Min → Min Age (field_session_min_age) converted to months
    • Course_Option/Age_Max → Max Age (field_session_max_age) converted to months
    • Course_Option/Location/Name → Location (field_session_location)
      • Location Name is used as a backup in case the Location Mapping does not match.
    • Course_Option/Location/Id → Location (field_session_location)
      • Location ID is used to attempt to match a location in the Location mapping in the Traction Rec importer settings (/admin/openy/integrations/traction-rec/importer)
    • Course_Option/Instructor → Instructor (field_session_instructor) trimmed to 255 characters
    • Course_Option/Available_Online → Online registration (field_session_online)
    • Course_Option/Available → Published (status)
    • Course_Option/Register_Online_From_Date → not used
    • Course_Option/Register_Online_To_Date → not used
    • Course_Option/Capacity → Initial Availability (field_availability)
    • Course_Option/Total_Capacity_Available → Initial Availability (field_availability)
    • Course_Option/Unlimited_Capacity → if set, overrides Capacity and sets Initial Availability (field_availability) to 100
    • Course_Option/Unlimited_Waitlist_Capacity → Wait list Unlimited Capacity (waitlist_unlimited_capacity)
    • Course_Option/Waitlist_Total → Wait list capacity (waitlist_capacity)
    • Course_Option/Product/Price_Description → Price description (field_price_description)
    • Course_Session/Id → Class (field_session_class) via a lookup to the Class import

Data Model

This module assumes a Traction Rec "standard" data model in its queries. Any deviations from this model will require overriding the queries in src/TractionRec.php.

This model contains a subset of the fields in Traction Rec that are relevant to our usage. All entities have more fields than listed.

Field types are taken from Salesforce's Setup > Object Manager > {Entity} > Fields & Relationships.

  • Number field options are: number(length_decimal places)
erDiagram
  Program_Category__c {
    id Id
    text(80) Name
  }
  Program__c {
    id Id
    text(80) Name
    checkbox Available__c
    textArea(255) Description__c
  }
  Program_Category_Tag__c {
    id Id
    autoNumber Name
    lookup(Program) Program__c
    lookup(Program_Category) Program_Category_c
  }
  Course__c {
    id Id
    text(80) Name
    checkbox Available__c
    text(128) Code__c
    longTextArea(640) Description__c
    lookup(Program) Program__c
    richTextArea Rich_Description__c
  }
  Course_Session__c {
    id Id
    text(80) Name
    checkbox Available__C
    text(128) Code__c
    lookup(Course) Course__c
    longTextArea(640) Description__c
    number(18_0) Num_Option_Entitlements__c
    lookup(ProductAndDiscount) Product__C
    richTextArea Rich_Description__c
    sum Total_Option_Capacity__c
    formula(number) Total_Option_Capacity_Remaining__C
    sum Total_Option_Registrants__c
    count Total_Options_Available__c
  }
  Course_Option__c {
    id Id
    text(80) Name
    number(3_1) Age_Max__c
    number(3_1) Age_Min__c
    checkbox Available__c
    number(18_0) Capacity__c
    picklist(multiSelect) Day_of_Week__c
    date End_Date__c
    text(8) End_Time__c
    text(128) Instructor__c
    lookup(ProductAndDiscount) Product__c
    number(18_0) Registration_Total_c
    longTextArea(3500) Setup_Notes__c
    number(3_0) Setup_Time_Required___c
    date Start_Date__c
    text(8) Start_Time__c
    longTextArea(3500) Tear_Down_Notes__c
    number(3_0) Tear_Down_Time_Required__C
  }
  Course_Session_Option__c {
    id Id
    autoNumber Name
    lookup(CourseOption) Course_Option__c
    masterDetail(CourseSession) Course_Session__c
    checkbox Option_Available__c
    number(18_0) Option_Capacity__c
    number(18_0) Option_Registration_Total__c
  }
  Program_Category__c ||--|{ Program_Category_Tag__c : &#34;&#34;
  Program__c ||--|{ Program_Category_Tag__c : &#34;&#34;
  Program__c ||--|{ Course__c : &#34;&#34;
  Course__c ||--|{ Course_Session__c : &#34;&#34;
  Course_Session__c ||--|{ Course_Session_Option__c : &#34;&#34;
  Course_Option__c ||--|{ Course_Session_Option__c : &#34;&#34;

Import

The module allows you to synchronize classes and programs from the Traction Rec CRM to the YMCA Website Services Program Event Framework (PEF).

It uses Migrate API to import data fetched from Traction Rec and provides Drush commands and a configuration UI.

The import process consists of 2 drush commands:

  1. openy-tr:fetch-all this command fetches required data from Traction Rec and saves it to JSON files.

    • Alias: tr:fetch
  2. openy-tr:import the command migrates fetched JSON files to YMCA Website Services and creates sessions, classes, activities, categories and programs.

    • Alias: tr:import

You can run the commands manually for one-time import or add both to cron jobs.

Other available drush commands:

  • openy-tr:rollback - Rolls back all imported nodes.

    • Alias: tr:rollback
  • openy-tr:reset-lock - Resets import lock.

    • Alias: tr:reset-lock
  • openy-tr:clean-up - Removes imported JSON files from the filesystem.

    • Alias: tr:clean-up
  • openy-tr:quick-availability-sync - Sync total availability data for sessions.

    • Alias: tr:qas

36 - Pull Requests review standard

Check more technical guidelines about our best practices for code quality.

Adherence to Standards

The YMCA Website Services Core Team will adhere to the same standards we set for the community for all areas of development and technologies as per the YMCA Website Services documentation.

The YMCA Website Services Core Team reserves the right to break these standards only in the following scenarios:

  • Emergency - a major defect or security risk has been discovered that requires extreme measures to resolve.
  • When the standards are broken, it is the responsibility of the YMCA Website Services Core Team to explain why the standards needed to be broken, and what the new standards will be moving forward.
  • This communication will be posted to the YMCA Website Services message board, Slack, and the documentation on GitHub will be updated to reflect the new standards.

Requirements for Pull Requests

  • Code in Pull Requests should follow our established best practices
  • Submitters’ profiles on GitHub or Drupal.org should be up to date and contain at least a name and organization.

Template for the PR

In order to create a good quality Pull Request, we prepared a PR template which is automatically added to new Pull Requests on GitHub.

List of requirements from the template:

  • Provide a link to the original issue, which is going to be fixed by the PR you are creating.
  • All coding styles are fulfilled and there are no issues reported by CodeSniffer. See Code of Conduct.
  • Documentation have been updated according to PR changes.
  • Steps for review have been provided according to PR changes.
    Steps for review
  • Make sure you’ve provided all necessary hook_update_N to support upgrade path.
  • Make sure your git email is associated with an account on drupal.org, otherwise you won’t get commits there.
    drupal.org email
  • If you would like to get credits on drupal.org, check documentation.

37 - Release processes

Repos involved in releases

  1. YMCA Website Services Drupal Profile Distribution YCloudYUSA/yusaopeny
  2. YMCA Website Services Project for initiating an YMCA Website Services instance - YCloudYUSA/yusaopeny-project
  3. Continuous Integration/DevOps for rebuilding/installing YMCA Website Services - YCloudYUSA/yusaopeny-cibox-build
  4. CIBox development environment (Virtualbox, Docker, Vagrant) YCloudYUSA/yusaopeny-cibox-vm
  5. Docksal development environment (Docker, VirtualBox) - YCloudYUSA/yusaopeny-docksal

Release Management

When tagging a new release of YMCA Website Services, the Lead Architect takes the following steps:

  1. Review/Merge/Update YCloudYUSA/yusaopeny-project (usually composer.json or/and oneline script install) and tag a new release there.
  2. Review/Merge all Pull Requests in YCloudYUSA/yusaopeny that were planned for release.
  3. Change the YMCA Website Services version in openy.info.yml.
  4. Change the YMCA Website Services version in major modules if there were changes to them (Activity Finder, PEF, etc).
  5. Create Changelog release notes as a draft and include Contributors as well as major issues fixed/introduced.
  6. Spin up a copy of an YMCA Website Services site and check top priority functionality for regressions.
  7. Send for review to Core Team (Craig Paulnock, Paige Kiecker), get approval.
  8. Change the YMCA Website Services version to next with -dev suffix for developers in openy.info.yml.
  9. Refresh the YMCA Website Services private mirror on the openy.cibox.tools CI server.
  10. Check that the one-click install is working on a fresh DigitalOcean instance ($10: 1CPU 2Gb RAM). Ensure the version of YMCA Website Services is the proper one in site info (admin/reports/status).
  11. Publish announcement in #developers YMCA Website Services Slack channel.
  12. Publish announcement in #general YMCA Website Services Slack channel.

38 - Release Schedule and Guidelines

YMCA Website Services Release Guidelines

YMCA Website Services releases major releases of the base project YMCA Website Services and Virtual Y quarterly. Minor releases and sub-project releases occur as needed.

Major releases (Quarterly)

Major releases are scheduled for the second Tuesday of the second month of each quarter (February, May, August, November). They are numbered 2.x and consist of:

  • New Features
  • New Enhancements
  • New Bugfixes

Minor Releases

Minor releases are numbered 2.x.x and consist of

  • Only bugfixes
  • Never have new features or major enhancements

Release schedule

2021

OpenY/VirtualY Releases for 2021

Prior years

39 - SA-CORE-2018-002 security update

This document is archived but may contain useful information for troubleshooting future updates. For updated update steps, visit How to upgrade YMCA Website Services.


To update your OpenY site with security fix from Drupal core https://www.drupal.org/sa-core-2018-002 OpenY team is suggesting 2 options- via patch and via Drupal core upgrade(or OpenY upgrade). Drupal core upgrade or OpenY upgrade is not always possible, but security issue should be fixed asap. So consider to apply patch and plan OpenY upgrade later.

How to apply patch

Patching OpenY releases 8.0.1 - 8.1.0 (Drupal core 8.2.x)

For patching your very old OpenY release it is highly recommended to upgrade OpenY to latest version or at least to one of the 8.1.1-8.1.6 (Drupal core 8.3.x) with Drupal core upgrade to 8.3.9 https://www.drupal.org/project/drupal/releases/8.3.9 . In case if it is not possible right now, follow steps below:

  • Login to your production server environment via SSH and find docroot folder of your site codebase. If you installed OpenY by following a tutorial - you should:
ssh -l root YOUR_SERVER_DOMAIN_NAME
cd /var/www/html
wget https://raw.githubusercontent.com/YCloudYUSA/yusaopeny-project/8.1.x/scripts/patches/8.2.x.patch

Now you are ready to patch your site. But before patching - make a backup of the file which is about to be patched

cp docroot/core/lib/Drupal/Core/DrupalKernel.php /var/backups/DrupalKernel.php

To patch your site run the command to test if the patch can be applied:

patch -p1 --dry-run < 8.2.x.patch

You should see a result

# patch -p1 --dry-run < 8.2.x.patch
checking file docroot/core/lib/Drupal/Core/DrupalKernel.php
checking file docroot/core/lib/Drupal/Core/Security/RequestSanitizer.php

In case if result different - stop on this step and let us know you have issue. In case if all good proceed with a command below, which will patch your site:

patch -p1 < 8.2.x.patch

You should see the same output as previously, but now your site is patched.

TIP: In case if you are using git repository for your site run

git add docroot/core/lib/Drupal/Core/DrupalKernel.php docroot/core/lib/Drupal/Core/Security && git commit -m "Patching OpenY core" && git push

to store your patched core into your own repository.

Patching OpenY releases 8.1.1 - 8.1.6 (Drupal core 8.3.x)

For patching your relatively old OpenY release it is highly recommended to upgrade OpenY to latest version or at least to one of the 8.1.7-8.1.10 (Drupal core 8.4.x) with Drupal core upgrade to 8.4.6 https://www.drupal.org/project/drupal/releases/8.4.6 . In case if it is not possible right now, follow steps below:

  • Login to your production server environment via SSH and find docroot folder of your site codebase. If you installed OpenY by following a tutorial - you should:
ssh -l root YOUR_SERVER_DOMAIN_NAME
cd /var/www/html
wget https://raw.githubusercontent.com/YCloudYUSA/yusaopeny-project/8.1.x/scripts/patches/8.3.x.patch

Now you are ready to patch your site. But before patching - make a backup of the file which is about to be patched

cp docroot/core/lib/Drupal/Core/DrupalKernel.php /var/backups/DrupalKernel.php

To patch your site run the command to test if the patch can be applied:

patch -p1 --dry-run < 8.3.x.patch

You should see a result

# patch -p1 --dry-run < 8.3.x.patch
checking file docroot/core/lib/Drupal/Core/DrupalKernel.php
checking file docroot/core/lib/Drupal/Core/Security/RequestSanitizer.php

In case if result different - stop on this step and let us know you have issue. In case if all good proceed with a command below, which will patch your site:

patch -p1 < 8.3.x.patch

You should see the same output as previously, but now your site is patched.

TIP: In case if you are using git repository for your site run

git add docroot/core/lib/Drupal/Core/DrupalKernel.php docroot/core/lib/Drupal/Core/Security && git commit -m "Patching OpenY core" && git push

to store your patched core into your own repository.

Patching OpenY releases 8.1.7 - 8.1.9 (Drupal core 8.4.x)

For patching your OpenY release it is highly recommended to upgrade OpenY to latest version (8.1.10 or never) or at least to one of the 8.1.10 (Drupal core 8.4.x) with Drupal core upgrade to 8.4.6 https://www.drupal.org/project/drupal/releases/8.4.6 . In case if it is not possible right now, follow steps below:

  • Login to your production server environment via SSH and find docroot folder of your site codebase. If you installed OpenY by following a tutorial - you should:
ssh -l root YOUR_SERVER_DOMAIN_NAME
cd /var/www/html
wget https://raw.githubusercontent.com/YCloudYUSA/yusaopeny-project/8.1.x/scripts/patches/8.4.x.patch

Now you are ready to patch your site. But before patching - make a backup of the file which is about to be patched

cp docroot/core/lib/Drupal/Core/DrupalKernel.php /var/backups/DrupalKernel.php

To patch your site run the command to test if the patch can be applied:

patch -p1 --dry-run < 8.4.x.patch

You should see a result

# patch -p1 --dry-run < 8.4.x.patch
checking file docroot/core/lib/Drupal/Core/DrupalKernel.php
checking file docroot/core/lib/Drupal/Core/Security/RequestSanitizer.php

In case if result different - stop on this step and let us know you have issue. In case if all good proceed with a command below, which will patch your site:

patch -p1 < 8.4.x.patch

You should see the same output as previously, but now your site is patched.

TIP: In case if you are using git repository for your site run

git add docroot/core/lib/Drupal/Core/DrupalKernel.php docroot/core/lib/Drupal/Core/Security && git commit -m "Patching OpenY core" && git push

to store your patched core into your own repository.

==========================

How to patch your Digitalocean OpenY install

In case if you have followed tutorial you should have your OPenY installed on you DigitalOcean server(droplet) in a predictable for current document folder. That’s why we prepared a short how to patch your OpenY site in a most simple way if you are not a Tech Guru, but just a user

  1. Log in as an admin user to your site admin UI by visiting /user/login URI page.
  2. Go to /admin/reports/status after login and search for Drupal Version string. It should be something like 8.2.x, 8.3.x or 8.4.x (x - some number too, like 8.4.2, for example). Based on your finding follow the steps below to your version
  3. Login to your ВigitalOcean cloud console at digitalocean.com and find Access Console in the dropdown for the droplet you are using for the OpenY image
  4. You should see a popup window with a black screen where console asks you for the login. Use root user and a password generated for you upon droplet creation.
  5. After login to a console run the command below, respectively to the version of your Drupal core.

One line script to patch 8.2.x Drupal core for OpenY

Type manually exact line

bash < <(curl -s https://raw.githubusercontent.com/YCloudYUSA/yusaopeny-project/8.1.x/scripts/patches/run8.2.x.sh)

and hit Enter. You should see OpenY was patched message.

One line script to patch 8.3.x Drupal core for OpenY

Type manually exact line

bash < <(curl -s https://raw.githubusercontent.com/YCloudYUSA/yusaopeny-project/8.1.x/scripts/patches/run8.3.x.sh)

and hit Enter. You should see OpenY was patched message.

One line script to patch 8.4.x Drupal core for OpenY

Type manually exact line

bash < <(curl -s https://raw.githubusercontent.com/YCloudYUSA/yusaopeny-project/8.1.x/scripts/patches/run8.2.x.sh)

and hit Enter. You should see OpenY was patched message.

40 - Sandboxes

YMCA Website Services Sandboxes for Evaluation and QA

The YMCA Website Services core team manages sandboxes for various configurations of the distribution to facilitate evaluation, to help with QA, and enable investigation of issues.

Getting started

Anyone can browse the sandboxes. Get started at sandboxes.y.org.

Get access to the sandboxes

To test the content editor experience or dig into the Drupal configuration you need to request login access by emailing us or asking anyone on the project team in the Y-USA Slack.

Behind the scenes

To learn more:

What’s in the sandboxes?

Each set of sandboxes contains 3 profile variations:

  • Standard
  • Extended
  • Custom

And three themes:

  • Carnation
  • Lily
  • Rose

And there are multiple sandbox environments:

Stable Sandboxes

sandboxes.y.org

These sandboxes are based on the latest stable release of YMCA Website Services. They are set to rebuild completely overnight and clear their database and files every 2 hours.

These sandboxes are built on CI by running:
composer create-project YCloudYUSA/yusaopeny-project buildnew --no-interaction --prefer-dist

ansible-playbook docroot/reinstall.yml -i /tmp/inventory5068801741271597001.ini -f 5 -e php_env_vars=APP_ENV=dev -e mysql_user=*** -e mysql_password=*** -e mysql_db=sandbox_carnation_custom -e drupal_folder=/var/www/sandbox_carnation_custom -e site_url=https://sandbox-carnation-cus.y.org -e pp_environment=demo -e run_reinstall=true -e "openy_profile_install_settings='openy_configure_profile.preset=complete openy_theme_select.theme=openy_carnation'" -e use_solr=false -i localhost, --connection=local -vvvv

Development Sandboxes

These sandboxes are based on the latest development version of YMCA Website Services or other branches as necessary. They are set to rebuild daily. Development sandboxes are rebuilt at the needs of the team and are not guaranteed. If one is not working, try another.

These sandboxes are built on CI by running:
composer create-project YCloudYUSA/yusaopeny-project:dev-9.2.x-development buildnew --no-interaction --prefer-dist

ansible-playbook docroot/reinstall.yml -i /tmp/inventory5068801741271597001.ini -f 5 -e php_env_vars=APP_ENV=dev -e mysql_user=*** -e mysql_password=*** -e mysql_db=sandbox_carnation_custom -e drupal_folder=/var/www/sandbox_carnation_custom -e site_url=https://sandbox-carnation-cus.y.org -e pp_environment=demo -e run_reinstall=true -e "openy_profile_install_settings='openy_configure_profile.preset=complete openy_theme_select.theme=openy_carnation'" -e use_solr=false -i localhost, --connection=local -vvvv

Feature-based sandboxes

We also maintain sandboxes with specific features enabled. Each of these builds

Virtual Y Sandboxes

These sandboxes are based on the YMCA Website Services stable Standard profile and the Virtual Experience Platform (aka “Virtual Y”, aka “Open Y Gated Content”) project.

Membership Framework Sandboxes

These are based on the YMCA Website Services stable Standard profile and the development version of the Membership Framework.

To rebuild the sandbox, CI is running:
composer create-project YCloudYUSA/yusaopeny-project buildnew --no-interaction --prefer-dist
cd buildnew
composer config minimum-stability dev
composer require "openy/openy_memberships":"dev-master as 1.0.0"
ansible-playbook docroot/reinstall.yml -i /tmp/inventory13097841656330601319.ini -f 5 -e php_env_vars=APP_ENV=dev -e mysql_user=*** -e mysql_password=*** -e mysql_db=d9_sandbox_carnation_std_membership_framework -e drupal_folder=/var/www/d9_sandbox_carnation_std_membership_framework -e site_url=https://sandbox-carnation-std-membership-framework-d9.y.org -e pp_environment=membership_framework -e run_reinstall=true -e "openy_profile_install_settings='openy_configure_profile.preset=standard openy_theme_select.theme=openy_carnation openy_select_content.content=0'" -e use_solr=false -i localhost, --connection=local -vvvv

Activity Finder Sandboxes

ThemeLinkWS ProfileActivity FinderThemeBootstrap
Carnationhttps://sandbox-carnation-cus-d9.y.org/activity-finder-v4stableCustomv4 devv4
Carnation (with TractionRec importer)https://traction-ws.y.org/stableCustomv4 devv4
Rosehttps://sandbox-rose-cus-d9.y.org/activity-finder-v4stableCustomv4 devv3
Lilyhttps://sandbox-lily-cus-d9.y.org/activity-finder-v4stableCustomv4 devv3
To rebuild the sandbox, CI is running:
composer create-project YCloudYUSA/yusaopeny-project:dev-9.2.x-development-af4 build --no-interaction --prefer-dist
cd ${WORKSPACE}/build
composer require YCloudYUSA/yusaopeny_activity_finder:"4.x-dev as 4.0"

ansible-playbook docroot/reinstall.yml -i /tmp/inventory4660848605526222353.ini -f 5 -e php_env_vars=APP_ENV=dev -e mysql_user=*** -e mysql_password=*** -e mysql_db=d9_sandbox_carnation_custom -e drupal_folder=/var/www/d9_sandbox_carnation_custom -e site_url=https://sandbox-carnation-cus-d9.y.org -e pp_environment=demo -e run_reinstall=true -e "openy_profile_install_settings='openy_configure_profile.preset=complete openy_theme_select.theme=openy_carnation'" -i localhost, --connection=local -vvvv

# Solr 4.5-4.9, Activity Finder v4
drush en -y search_api_solr_legacy openy_prgf_activity_finder_4 || true
drush cset -y search_api.server.solr backend_config.connector_config.host 127.0.0.1 -y || true
drush cset -y search_api.server.solr backend_config.connector_config.core ${VHOST_FOLDER} -y
drush cset -y search_api.server.solr backend_config.connector_config.solr_version 4.5 -y
drush search-api-mark-all || true
drush sapi-i || true
drush en -dvy openy_prgf_af4_demo || true

# Solr 4.5-4.9, Activity Finder v4, Carnation theme, bootstrap v4
drush cset -y openy_activity_finder.settings bs_version 4 || true

41 - Secure devops for composer 2 release

This article only applies to long-term users of YMCA Website Services. YMCA Website Services supports Composer 2 as of version 8.2.7 in November 2020 and new installs use Composer 2 by default.


Composer was upgraded to 2.x on October 30, 2020. This could cause instability when your older composer 1.x accidentally auto-updates to the 2.x version. Issues could include: composer fails to run any commands and blocks OpenY upgrade/maintenance. The instability would be in the developer environment, not YMCA Website Services/Drupal.

The YMCA Website Services team prepared an avoidance plan for the community to take action steps before the release while YMCA Website Services will be verifying Composer 2.x causes no issues or regressions.

If you use Docksal or Vagrant local environments your composer version will not update automatically, so you’re currently safe from inadvertent updates. Instructions for updating those environments will be included with any necessary YMCA Website Services updates at a later date.

Case before October 30, 2020, when you are on composer 1.x

Composer 2 is coming and older versions of composer 1.x show the message below.

Composer 2.0 is about to be released and the older 1.x releases will self-update directly to it once it is released. To avoid surprises update now to the latest 1.x version

If you see the message above, ensure your environments have updated composer to the latest 1.x version by running:

composer selfupdate --1

To ensure the above command shows your version 1.x after an upgrade, check the version of composer:

composer --version

You should see something like

MacBook-Pro-Andrii:www podarok$ composer --version
Composer version 1.10.15 2020-10-13 15:59:09

as an output of the command.

If you do not upgrade to the latest 1.x version before October 30, 2020. i.e. if you accidentally upgrade to Composer 2.x

If your composer updated to version 2 and you have issues with this upgrade, the solution is to downgrade Composer to the latest 1.x version by running:

composer selfupdate --1

If you are faced with any issues connect with the YMCA Website Services team on GitHub ( create issue) and the #developers channel on Slack.

42 - Server Requirements

If you need to prepare server for the YMCA Website Services instance, here below you should find all needed software to meet its requirements.

List of requirements

  1. Ubuntu LTS (14 or 16) is preferred. CentOS is ok as well. Or even any other Linux distribution, but was not tested by YMCA Website Services team so far.

  2. (Drupal 8 server requirements should be met)[https://www.drupal.org/docs/system-requirements/php-requirements].

  3. PHP 5.6+ (PHP 7 is better in terms of performance)

List of PHP modules server should have:

  • php{{ php_version }}
  • php{{ php_version }}-mcrypt
  • php{{ php_version }}-cli
  • php{{ php_version }}-common
  • php{{ php_version }}-curl
  • php{{ php_version }}-dev
  • php{{ php_version }}-fpm
  • php{{ php_version }}-gd
  • php{{ php_version }}-mysql
  • php{{ php_version }}-memcached
  • php{{ php_version }}-imagick
  • php{{ php_version }}-xml
  • php{{ php_version }}-xdebug
  • php{{ php_version }}-mbstring
  • php{{ php_version }}-soap
  • php{{ php_version }}-zip
  1. MySQL 5.5+ . Here are the best settings https://github.com/cibox/cibox/blob/master/core/facade-mysql/defaults/main.yml to get it fast and furious
  2. Apache 2 with mod-php (preffered for stability) or nginx with php-fpm (better for speed and scalability)
  • libapache2-mod-php{{ php_version }}
  1. Memcache server (optional)

  2. Server tools

  • Ansible (optional)
  • Docker (optional)
  • SOLR 4.x (if there will be requirement for SOLR search support)
  • Varnish (optional)

44 - Start new YMCA Website Services project

Here you can find instructions how you can start project based on YMCA Website Services distribution.

New project from scratch based on YMCA Website Services

In order to start new project from scratch, you can use installation instructions that will build your project and even add development environment.

Add YMCA Website Services to existing Drupal 8 project

Please take a look at the full composer.json file below that you should eventually get.

 Example composer.json (Drupal 8.3.2 + YMCA Website Services 1.2)
{
    "name": "drupal/drupal",
    "description": "Drupal is an open source content management platform powering millions of websites and applications.",
    "type": "project",
    "license": "GPL-2.0+",
    "require": {
        "composer/installers": "^1.0.24",
        "wikimedia/composer-merge-plugin": "~1.4",
        "YCloudYUSA/yusaopeny": "8.*.*",
        "cweagans/composer-patches": "~1.0"
    },
    "minimum-stability": "dev",
    "prefer-stable": true,
    "config": {
        "preferred-install": "dist",
        "autoloader-suffix": "Drupal8",
        "secure-http": false
    },
    "extra": {
        "_readme": [
            "By default Drupal loads the autoloader from ./vendor/autoload.php.",
            "To change the autoloader you can edit ./autoload.php.",
            "This file specifies the packages.drupal.org repository.",
            "You can read more about this composer repository at:",
            "https://www.drupal.org/node/2718229"
        ],
        "merge-plugin": {
            "include": [
                "core/composer.json"
            ],
            "recurse": false,
            "replace": false,
            "merge-extra": false
        },
        "installer-paths": {
          "core": ["type:drupal-core"],
          "libraries/{$name}": ["type:drupal-library"],
          "modules/contrib/{$name}": ["type:drupal-module"],
          "profiles/contrib/{$name}": ["type:drupal-profile"],
          "themes/contrib/{$name}": ["type:drupal-theme"],
          "drush/contrib/{$name}": ["type:drupal-drush"],
          "modules/custom/{$name}": ["type:drupal-custom-module"],
          "themes/custom/{$name}": ["type:drupal-custom-theme"]
        },
        "enable-patching": true
    },
    "autoload": {
        "psr-4": {
            "Drupal\Core\Composer\": "core/lib/Drupal/Core/Composer"
        }
    },
    "scripts": {
        "pre-autoload-dump": "Drupal\Core\Composer\Composer::preAutoloadDump",
        "post-autoload-dump": [
          "Drupal\Core\Composer\Composer::ensureHtaccess"
        ],
        "post-package-install": "Drupal\Core\Composer\Composer::vendorTestCodeCleanup",
        "post-package-update": "Drupal\Core\Composer\Composer::vendorTestCodeCleanup",
        "post-install-cmd": [
            "bash scripts/remove_vendor_git_folders.sh || :"
        ],
        "post-update-cmd": [
            "bash scripts/remove_vendor_git_folders.sh || :"
        ]
    },
    "repositories": [
        {
            "type": "composer",
            "url": "https://packages.drupal.org/8"
        },
        {
            "type": "package",
            "package": {
                "name": "library-kenwheeler/slick",
                "version": "1.6.0",
                "type": "drupal-library",
                "source": {
                    "url": "https://github.com/kenwheeler/slick",
                    "type": "git",
                    "reference": "1.6.0"
                }
            }
        },
        {
            "type": "package",
            "package": {
                "name": "library-dinbror/blazy",
                "version": "1.8.2",
                "type": "drupal-library",
                "source": {
                    "url": "https://github.com/dinbror/blazy",
                    "type": "git",
                    "reference": "1.8.2"
                }
            }
        },
        {
            "type": "package",
            "package": {
                "name": "library-gdsmith/jquery.easing",
                "version": "1.4.1",
                "type": "drupal-library",
                "source": {
                    "url": "https://github.com/gdsmith/jquery.easing",
                    "type": "git",
                    "reference": "1.4.1"
                }
            }
        },
        {
            "type": "package",
            "package": {
                "name": "library-enyo/dropzone",
                "version": "4.3.0",
                "type": "drupal-library",
                "source": {
                    "url": "https://github.com/enyo/dropzone",
                    "type": "git",
                    "reference": "v4.3.0"
                }
            }
        },
        {
            "type": "package",
            "package": {
                "name": "library-jaypan/jquery_colorpicker",
                "version": "1.0.1",
                "type": "drupal-library",
                "source": {
                    "url": "https://github.com/jaypan/jquery_colorpicker",
                    "type": "git",
                    "reference": "da978ae124c57817021b3166a31881876882f5f9"
                }
            }
        },
        {
            "type": "package",
            "package": {
                "name": "library-ckeditor/panelbutton",
                "version": "4.7.0",
                "type": "drupal-library",
                "dist": {
                    "url": "http://download.ckeditor.com/panelbutton/releases/panelbutton_4.7.0.zip",
                    "type": "zip"
                }
            }
        },
        {
            "type": "package",
            "package": {
                "name": "library-ckeditor/colorbutton",
                "version": "4.7.0",
                "type": "drupal-library",
                "dist": {
                    "url": "http://download.ckeditor.com/colorbutton/releases/colorbutton_4.7.0.zip",
                    "type": "zip"
                }
            }
        },
        {
            "type": "package",
            "package": {
                "name": "library-ckeditor/colordialog",
                "version": "4.7.0",
                "type": "drupal-library",
                "dist": {
                    "url": "http://download.ckeditor.com/colordialog/releases/colordialog_4.7.0.zip",
                    "type": "zip"
                }
            }
        },
        {
            "type": "package",
            "package": {
                "name": "library-ckeditor/glyphicons",
                "version": "2.2",
                "type": "drupal-library",
                "dist": {
                    "url": "http://download.ckeditor.com/glyphicons/releases/glyphicons_2.2.zip",
                    "type": "zip"
                }
            }
        }
    ]
}
  1. Add "YCloudYUSA/yusaopeny": "8.*.*" to the require section in your composer.json, like here

  2. Add all required repositories that are listed here to your composer.json

  3. Add installer path as here to your composer json. See example.

  • composer.json inside of docroot Installer path will look like this:

    "installer-paths": {
        "core": ["type:drupal-core"],
        "libraries/{$name}": ["type:drupal-library"],
        "modules/contrib/{$name}": ["type:drupal-module"],
        "profiles/contrib/{$name}": ["type:drupal-profile"],
        "themes/contrib/{$name}": ["type:drupal-theme"],
        "drush/contrib/{$name}": ["type:drupal-drush"],
        "modules/custom/{$name}": ["type:drupal-custom-module"],
        "themes/custom/{$name}": ["type:drupal-custom-theme"]
    }
    
  • composer.json outside of docroot Installer path will look like this:

    "installer-paths": {
        "docroot/core": ["type:drupal-core"],
        "docroot/libraries/{$name}": ["type:drupal-library"],
        "docroot/modules/contrib/{$name}": ["type:drupal-module"],
        "docroot/profiles/contrib/{$name}": ["type:drupal-profile"],
        "docroot/themes/contrib/{$name}": ["type:drupal-theme"],
        "drush/contrib/{$name}": ["type:drupal-drush"],
        "docroot/modules/custom/{$name}": ["type:drupal-custom-module"],
        "docroot/themes/custom/{$name}": ["type:drupal-custom-theme"]
    }
    
  1. Add "cweagans/composer-patches": "~1.0" to the require section in you composer.json. See example.

  2. Add "enable-patching": true to the extra section in your composer.json See example.

  3. Add "secure-http": false to the config section in your composer.json See example.

  4. Remove composer.lock and vendor folder from the project if they are exist in your folder.

  5. Remove "replace" section from your composer.json

  6. (Optional) If you keep vendor folder in your git repository, we recommend to clean up project from .git folder inside modules and libraries. To do so

  • Add cleaner script to your project from YMCA Website Services composer package. You can just copy it and paste onto your project.

  • Adjust folders that you would like to cleanup

  • Execute it in post-install-cmd and post-update-cmd:

    "post-install-cmd": [
        "bash scripts/remove_vendor_git_folders.sh || :"
    ],
    "post-update-cmd": [
        "bash scripts/remove_vendor_git_folders.sh || :"
    ]
    
  1. Run composer install

CIBox

In this section you can learn how to configure development environment and CI server using Open Source product CIBox.

Create project

  1. Generate project based on this quickstart

  2. Add YMCA Website Services to the project using (Add YMCA Website Services to already existing Drupal 8 project)

  3. Init git and add initial commit

cd OPENY_PROJECT
git init
git commit -m "Init YMCA Website Services project"
git remote add origin git@github.com:NAMESPACE/PROJECT.git
git push -u origin master
  1. Spin up your local vagrant machine
vagrant up --provision
  1. Setup CI server for new project based on CIBox documentation.
  • Follow quick start starting from Jenkins Provisioning Step http://docs.cibox.tools/en/latest/Quickstart/#jenkins-provisioning (Here we will get PR builds and DEMO site (DEV environment) with credentials to it )
  • Setup hosting STAGE environment (it should be a 1:1 copy of existing or expected hosting account for ability to provide performance testing there)
  • Setup deployment plans for CI by reusing DEMO builder job

Install YMCA Website Services on DigitalOcean

  1. Create new Droplet using “One-click apps” image Drupal 8.*.* on 14.04
  2. Login to server via SSH or web console
  3. Run command
bash <(curl -s https://raw.githubusercontent.com/YCloudYUSA/yusaopeny/8.x-1.x/build/openy-digital-ocean.sh)
  1. Open link(e.g. http://IP/core/install.php) from console output and finish YMCA Website Services installation

Video tutorial

YMCA Website Services v1.0b - Install Tutorial

End to end installation

YMCA Website Services install - in 16 minutes end to end, no tutorial

45 - technology pipeline

To deliver the best technologies for the YMCA movement, the YMCA Website Services development community maintains the following documents and best practices:

  1. Development FAQ
  2. YMCA Website Services Coding Standards
  3. How new technologies and features are added to YMCA Website Services
  4. Sandboxes
  5. Smoke Tests
  6. A Slack Team by invite with a #developers channel where we discuss technical issues with our partners and YUSA.
  7. A YouTube playlist for Developers
  8. A list of 3rd party dependencies which are reviewed periodically for new features and deprecations.

46 - Terms and Conditions

These Terms & Conditions must be agreed to upon installing YMCA Website Services

These terms are maintained in the distribution codebase at TermsOfUseForm.php and are subject to change at any time. Any change in the terms will require site owners to agree to the new terms and a record of the date of agreement is maintained in the site database. Terms can be viewed on your site at Admin > YMCA Website Services > Terms and Conditions (/admin/openy/terms-and-conditions).


  • We agree to the Participant Agreement and Terms of Use
  • YMCA of the USA supports the Website Services platform with respect to use by its Member Associations but is not responsible for and does not control the services provided by 3rd party agencies, which are using and modifying YMCA Website Service distribution.
  • YMCA of the USA recommends that each participating YMCA association develop and implement its own cybersecurity policies and obtain cyber liability and data privacy insurance.
  • I acknowledge that YMCA Website Service is open source content and that all content is provided “as is” without any warranty of any kind. YMCA of the USA makes no warranty that its services will meet your requirements, be safe, secure, uninterrupted, timely, accurate, or error-free, or that your information will be secure. YMCA of the USA will not maintain and support YMCA Website Service templates indefinitely. The entire risk as to the quality and performance of the content is with you.
  • YMCA of the USA recommends obtaining a reputable agency to assist with the implementation of the YMCA Website Service platform and further development for your specific needs.
  • All demonstration content, including but not limited to text, images, graphics, videos, audio, and any other materials displayed on this website, is the exclusive property of YMCA of the USA. The demonstration content is provided solely for illustrative purposes and to showcase the capabilities of YMCA’s Website Service. Nonetheless, YMCA member associations may use demonstration content for their websites, as applicable.
    • By accessing and/or using this website, you agree to respect the ownership and intellectual property rights of YMCA of the USA over the demonstration content. Users and visitors are strictly prohibited from reproducing, distributing, modifying, or otherwise using the demonstration content without explicit written permission from YMCA of the USA.
    • Any unauthorized use or misuse of the demonstration content is a violation of these Terms and Conditions and may be subject to applicable laws and regulations, result in your access being revoked, and/or legal action taken, if applicable.
    • YMCA of the USA reserves the right to change, modify, or remove the demonstration content from the website at any time without prior notice. We are not responsible for any inaccuracies or errors in the demonstration content and make no guarantees about its accuracy or completeness.

47 - Testing YMCA Website Services for PHP 7.4 version support

Requirements

  • php-cli 7.4 ( memory_limit value should be large ( 2000M ) or unlimiter ( -1 ) in order to not fail
  • composer 2

Steps

  1. Obtain latest development code of YMCA Website Services
composer create-project YCloudYUSA/yusaopeny-project:9.2.x-development-dev openy7.4
  1. Add phpcompatibility to require-dev section
cd open7.4
composer require --dev phpcompatibility/php-compatibility
./vendor/bin/phpcs -p . --standard=PHPCompatibility --runtime-set testVersion 7.4 --config-set installed_paths vendor/phpcompatibility/php-compatibility
  1. Generate report
./vendor/bin/phpcs -p . --standard=PHPCompatibility --runtime-set testVersion 7.4 --report-file=report.txt

or if you need to skip warnings

./vendor/bin/phpcs -p . --standard=PHPCompatibility --runtime-set testVersion 7.4 --report-file=report.txt -n

In report.txt you’d find a full list of findings to be resolved in order to pass compatibility

48 - Tests

These instructions explain how you can run tests.

Behat

Requirements

Run full test suite

  1. Execute command

    $ cd profiles/contrib/openy
    $ sh runtests.sh
    
  2. Open http://site.com/profiles/contrib/openy/build/reports/behat in browser.

Run selenium container + Behat tests in usual way

In order to run only selenium container + behat in usual way:

$ cd profiles/contrib/openy
$ sh runtests.sh --tags run_selenium
$ bin/behat

Stop selenium container

In order to stop selenium container:

$ cd profiles/contrib/openy
$ sh runtests.sh --tags stop_selenium

If necessary, edit behat.local.yml to match your environment.

Visual debugging - Video

When you develop JS tests, it’s important to see what’s going on the Selenium screen. You can easily see this during development.

  1. Install https://www.realvnc.com/download/viewer
  2. Run selenium using command
$ cd profiles/contrib/openy
$ sh runtests.sh --tags run_selenium
  1. Open installed VNC Viewer and connect to the server with IP 192.168.56.132:5901
  • Password = secret
  1. Run tests and you should see everything that is performed by behat tests in VNC client
$ bin/behat

Debugging JavaScript Behat tests

Custom Behat functionality

  • Create entities in table forms, with key to use in reference and reference entities by key.
    • KEY is optional, and must be all CAPS.
    • Taxonomy
      Given I create "taxonomy_term" of type "color" with key for reference:
        | KEY  | name  | field_color |
        | Blue | Blue  | 0000FF      |
        | Red  | Red   | FF0000      |
      
    • Paragraphs
      Given I create "paragraph" of type "small_banner" with key for reference:
        | KEY     | field_prgf_headline | field_prgf_color |
        | banner1 | Headline 1          | Blue             |
        | banner2 | Headline 2          | Red              |
      
    • Media entities
      Given I create "media" of type "image" with key for reference:
        | KEY       | name            | file         |
        | gallery_1 | Gallery image 1 | gallery.png  |
        | gallery_2 | Gallery image 2 | gallery2.png |
        | gallery_3 | Gallery image 3 | gallery3.png |
      
  • Create nodes in table forms, with key to use in reference and reference entities by key.
    • KEY is optional, and must be all CAPS.
    • Basic create
      Given I create "landing_page" content:
        | KEY       | title           | field_lp_layout | field_content |
        | landing_1 | Test Landing 01 | one_column      | banner1       |
        | landing_2 | Test Landing 02 | one_column      | banner2       |
      
    • Vertical field table
      Given I create large "landing_page" content:
        | KEY             | landing_3       | landing_4       |
        | title           | Test Landing 03 | Test Landing 04 |
        | field_lp_layout | one_column      | one_column      |
        | field_content   | banner1         | banner2         |
      
    • Create & view immediately
      Given I view a "landing_page" content:
        | KEY             | landing_5       |
        | title           | Test Landing 05 |
        | field_lp_layout | one_column      |
        | field_content   | banner1         |
      
    • Multiple referenced entities by key on a field.
      Given I create "landing_page" content:
        | KEY       | title           | field_lp_layout | field_content    |
        | landing_6 | Test Landing 06 | one_column      | banner1, banner2 |
      

Example Address and Latitude + Longitude

Fields with sub field/columns: The machine name and columns can be found in the form markup in the field name property. Inspect form field name depicted The first portion, field_location_address represents the Drupal field machine name, while the second array key address_line1 represents the column.

  • Add Address
    Given I view a "branch" content:
        | title                                | Branch Example  |
        | field_location_address:country_code  | US             |
        | :address_line1                       | Main road 10   |
        | :locality                            | Seattle        |
        | :administrative_area                 | WA             |
        | :postal_code                         | 98101          |
    
  • Add Latitude and Longitude
    Given I view a "branch" content:
      | title                          | Branch Example 2 |
      | field_location_coordinates:lat | 47.293433        |
      | :lng                           | -122.238717      |
      | field_location_phone           | +1234567890      |
    

49 - Theming and Design

Welcome to YMCA Website Services Theming and Design documentation.

How to change styles on content type level

Given: As an YMCA Website Services site developer, I want to be able to easily change the CSS for a Camp page independently from a Location page, so I can better customize the site to meet the needs of my customers.

How to:

  • If you need to change CSS on some pages independently, you should enable Custom CSS functionality on the theme configuration page - Custom CSS - check “Enable or disable custom CSS”.
  • Input CSS code into the textarea.

In order to change CSS on each particular page you should use the following selectors:

  • .page-node-type-{node type};
  • .node-id-{node ID};
  • .path-frontpage.

The existing node types are: activity, alert, blog, branch, camp, class, facility, landing-page, membership, news, program, program-subcategory, session.

50 - Tour

How to use YMCA Website Services Tour Token with Tour

In someone modules have tour tips and for more interactivity, you can add a token with a click to any selector.

  1. In the module open tour yml file. Configuration project add/update form

  2. Select the tip for edit and in body add token like this [openy_tour:click:button_name:selector] Configuration project add/update form

  3. Create hook update for you changes and in command line run drush updb -y

Token components:

[openy_tour:click:button_name:selector]*

openy_tour - token name;

click - command in the token;

button_name - name of button when show in a tip;

selector - selector to be clicked.

Please see and use jQuery selectors.

51 - Upgrade OpenY 8.1.3 to 8.2.2.1

This document is archived but may contain useful information for troubleshooting future updates. For updated update steps, visit How to upgrade YMCA Website Services.


Video tutorials

Upgrade OpenY from 8.0.7 to 8.2.2.1 - https://www.youtube.com/watch?v=U_mg0-yKGOI

Document is work in progress

These are instructions for upgrading a very old version of YMCA Website Services to the latest version. Given the fact Drupal 8.7+ has no support for automatic entity updates ( BaseFieldDefinitions ) we have to upgrade to 8.2.2.1 of OpenY, which is still on 8.6 Drupal Core, and then update to the latest YMCA Website Services version as usual.

Environment

vagrant@vagrant:/var/www/docroot$ uname -a
Linux vagrant 4.15.0-29-generic #31-Ubuntu SMP Tue Jul 17 15:39:52 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
vagrant@vagrant:/var/www/docroot$ lsb_release -a
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 18.04.1 LTS
Release:	18.04
Codename:	bionic
vagrant@vagrant:/var/www/docroot$ php -v
**PHP 7.1.31-1**+ubuntu18.04.1+deb.sury.org+1 (cli) (built: Aug  7 2019 10:23:12) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2018 Zend Technologies
    with Zend OPcache v7.1.31-1+ubuntu18.04.1+deb.sury.org+1, Copyright (c) 1999-2018, by Zend Technologies
    with Xdebug v2.7.2, Copyright (c) 2002-2019, by Derick Rethans
vagrant@vagrant:/var/www/docroot$ drush --version
 **Drush Version   :  8.2.3**
vagrant@vagrant:/var/www/docroot$ composer --version
**Composer version 1.7.2** 2018-08-16 16:57:12

Step by step guide for update

  • Use PHP7.1 for upgrade and install php7.1-mysql php7.1-mcrypt php7.1-cli php7.1-common php7.1-curl php7.1-dev php7.1-fpm php7.1-gd php7.1-mysql php7.1-memcached php7.1-imagic php7.1-xml php7.1-xdebug php7.1-mbstring php7.1-soap php7.1-zip php7.1-xml
  • Go to the folder of OpenY code tree where docroot folder is contained
  • mv composer.json composer.json.orig
  • wget https://raw.githubusercontent.com/YCloudYUSA/yusaopeny-project/8.2.x/composer.json
  • mkdir -p scripts ; cd scripts && wget https://raw.githubusercontent.com/YCloudYUSA/yusaopeny-project/8.2.x/scripts/remove_libraries_gitignore_files.sh && cd ..
  • composer require YCloudYUSA/yusaopeny:8.2.2.1 --no-suggest --no-update
  • composer install --ignore-platform-reqs --no-suggest
  • composer update --prefer-stable --no-suggest
  • cd docroot
  • drush dl -y plugin-8.x-2.5 contribute-8.x-1.0-beta7 scheduler-8.x-1.0 views_block_filter_block datalayer simple_menu_icons rabbit_hole metatag simple_sitemap-8.x-3.0 easy_breadcrumb-8.x-1.6
  • drush en openy_upgrade_tool openy_er openy_prgf_loc_finder openy_map openy_data_wrapper openy_loc_branch content_moderation focal_point
  • drush ev "Drupal::service('module_installer')->install(['openy']);" <- This steps fixes some hidden bug when openy profile removed from core.extension configuration for unknown reason.
  • Manual step (optional, if you have issues with drush updatedb): Edit all yml files in profiles folder to comment media.type.image , field.field.node.program.field_header_content, field.field.node.branch.field_location_amenities in dependencies sections.

image

image

image

  • run drush updatedb -y <- this will fail for the first time ( Media not installed yet ), disregard
  • run drush updatedb -y <- this should run properly.
  • run drush entup

52 - Upgrade path

All changes in configurations should be added to appropriate hook_update_N in order to update already existing environments. We suggest to use https://www.drupal.org/project/confi for working with hook_update_N.

openy.install in profile

In this file we should put updates that are related to the distribution in general and don’t fit into any feature.

  • Enable/Disable module
  • General configs

openy_*.install in modules

In case if you update some configuration for specific feature, make sure that you put updates into appropriate module.

Revert only specific property from config

With config_import module help we can update only part from full config.

For updating specific property in config (use service ‘openy_upgrade_tool.param_updater’):

  1. go to related to this config module

  2. create new hook_update_N in openy_*.install file

  3. in update add next code (this is example):

$config = drupal_get_path('module', 'openy_media_image') . '/config/install/views.view.images_library.yml';
$config_importer = \Drupal::service('openy_upgrade_tool.param_updater');
$config_importer->update($config, 'views.view.images_library', 'display.default.display_options.pager');

Where:

  • $config variable contains path to config with config name
  • “views.view.images_library” - config name
  • “display.default.display_options.pager” - config specific property (you can set value from a nested array with variable depth)

Revert full configs

For updating full config or several configs from directory use service ‘openy_upgrade_tool.importer’.

$config_dir = drupal_get_path('module', 'openy_media_image') . '/config/install';
$config_importer = \Drupal::service('openy_upgrade_tool.importer');
$config_importer->setDirectory($config_dir);
$config_importer->importConfigs(['views.view.images_library']);

Where:

  • $config_dir - path to directory with config
  • “views.view.images_library” - config name

Also you can update several configs from directory:

$config_importer->importConfigs([
  'views.view.images_library',
  'views.view.example_view',
]);

53 - Upgrade to Open Y 1.x

This document is archived but may contain useful information for troubleshooting future updates. For updated update steps, visit How to upgrade YMCA Website Services.


Upgrade to old, Open Y 1.x version ( tested on upgrading 8.0.2 to 8.1.1.14 )

See upgrade from 8.1.3 to 8.2.2.1

We found the oldest OpenY instance working on 8.0.2 version of OpenY so this document should cover all the way of updating it to the latest version.

Prepare dedicated environment for upgrade testing

Ensure you have working computer or virtual machine with

  • Ubuntu 14.04(16.04 or any decent Ubuntu LTS versions) 64 bit
  • MySQL 5.5+
  • Apache 2.4
  • PHP 5.6-7.1 (7.2 is not supported yet)

OpenY team maintains Vagrant preconfigured Virtualbox based virtual machine with OpenY. Feel free to use it to get working virtual environment. Your own OpenY instance should have Virtual machine injected into your site codebase. Just find Vagrantfile and proceed with vagrant up accordingly to the documentation.

Obtain local copy of your production site

You have to create local copy of your site locally to be able to proceed with the upgrade. For that

  • Make a backup of your production database and copy it to your local machine
  • Make a copy of your production site codebase and copy it to your local machine

  1. Detect version of your OpenY

Starting from OpenY 1.10 release you should see a version of OpenY in your site reports dashboard. For previous versions the best way to check your version is to analyze creation date of index.php pr README.txt file in the docroot folder of your site and compare it to the release date from https://github.com/YCloudYUSA/yusaopeny/releases . Your OpenY version should be the one which is older than creation date of the files.

  1. Run command with next never version

In a same folder where is your docroot folder run

mv composer.json composer.json.bak || true
wget https://raw.githubusercontent.com/YCloudYUSA/yusaopeny-project/8.1.x/composer.json
cd docroot/profiles/contrib/openy/
rm -f yparse*
wget https://raw.githubusercontent.com/YCloudYUSA/yusaopeny-project/8.1.x/scripts/yparse.sh
drush cr
sh yparse.sh | xargs drush en -y
cd ../../../../
composer require YCloudYUSA/yusaopeny:NEW_VERSION_HERE --no-update
composer update --prefer-dist --with-dependencies --prefer-stable --update-with-all-dependencies --no-suggest
  1. Update the site

Go to docroot folder of your codebase and run

drush updatedb
drush entup

Sometimes, when updatedb fails, it is important to get stable version of some modules we found causing problems

drush dl -y plugin-8.x-2.5 contribute-8.x-1.0-beta7 scheduler-8.x-1.0 views_block_filter_block datalayer simple_menu_icons rabbit_hole metatag simple_sitemap-8.x-2.9 easy_breadcrumb-8.x-1.6
drush en -y plugin contribute scheduler views_block_filter_block datalayer simple_menu_icons rabbit_hole metatag simple_sitemap || true
drush ev "Drupal::service('module_installer')->install(['content_moderation','openy']);"

Ensure commands above finished with no error messages. Best way to check it - run them one more time. If next run shows

$ drush updatedb
No database updates required                                                                                    [success]
$ drush entup
No entity schema updates required                                                                               [success]

You almost 100% proved updated were executed correctly.

  1. Check for regressions

  1. Backup current state of the updated site

  1. Proceed with an update to next version until succeeded (Start from item 1)

54 - Upgrade use case from 8.2.2.3 to 8.2.7.3

This document is archived but may contain useful information for troubleshooting future updates. For updated update steps, visit How to upgrade YMCA Website Services.


1 uninstall lndr and optimizely modules before running composer update commands

2 config to remove


drush cdel image.style.browser_thumbnail

3 enable openy_focal_point and media_directories_ui should be enabled when upgrade from 8.2.2.3 to 8.2.7.3

4 - run drush updatedb and next steps from tutorial

55 - Upgrading from 9.2.11.5 to 10.3

Scenario

A YMCA website is currently running on Y USA Open Y (openy-9.x-2.11.5) using Drupal 9. They want to upgrade to the latest YMCA Website Services distribution (10.3) on Drupal 10.

Upgrade Steps

  1. Prepare for Upgrade to WS

    • Ensure your site is on the latest Y USA Open Y 9.x release

      composer require -W ycloudyusa/yusaopeny:9.2.13.0 drupal/core-project-message:^9.5  drupal/core-composer-scaffold:^9.5 drupal/core-recommended:^9.5
      
    • Run database updates

      ../vendor/drush/drush/drush updatedb -l $SITE_URL
      
  2. Upgrade to WS 10.2

    • Require the 10.2.14 release of Y USA Open Y and update Drupal core and dependencies

      composer require -W ycloudyusa/yusaopeny:10.2.14 drupal/core-project-message:^10.0.11  drupal/core-composer-scaffold:^10.0.11 drupal/core-recommended:^10.0.11 drupal/core:^10.0.11 'drupal/smtp:^1.4' consolidation/robo:^4
      
  3. Address QuickEdit/RDF Dependency Issue

    • Temporarily require QuickEdit and RDF

      composer require drupal/quickedit drupal/rdf
      
    • Run database updates

      ../vendor/drush/drush/drush updatedb -l
      
    • Remove and re-add QuickEdit to resolve dependency conflicts

      composer remove drupal/quickedit
      composer require drupal/quickedit drupal/rdf
      
  4. Upgrade to WS 10.3.0.1

    • Require the 10.3.0.1 release

      composer require -W ycloudyusa/yusaopeny:10.3.0.1 drupal/core-project-message:^10.0.11  drupal/core-composer-scaffold:^10.0.11 drupal/core-recommended:^10.0.11 drupal/core:^10.0.11
      
    • Run database updates

      ../vendor/drush/drush/drush updatedb -l $SITE_URL
      
  5. Upgrade to WS 10.3.1

    • Require the 10.3.1 release

      composer require -W ycloudyusa/yusaopeny:10.3.1 drupal/core-project-message:^10.0.11  drupal/core-composer-scaffold:^10.0.11 drupal/core-recommended:^10.0.11 drupal/core:^10.0.11
      
  6. Add CKEditor5 Paste Filter

    • Require the CKEditor5 Paste Filter module

      composer require drupal/ckeditor5_paste_filter
      
    • Run database updates

      ../vendor/drush/drush/drush updatedb -l $SITE_URL
      
  7. Upgrade to WS 10.3.2

    • Require the 10.3.2 release

      composer require -W ycloudyusa/yusaopeny:10.3.2 drupal/core-project-message:^10.0.11  drupal/core-composer-scaffold:^10.0.11 drupal/core-recommended:^10.0.11 drupal/core:^10.0.11
      
  8. Upgrade to WS 10.3.3.2

    • Require the 10.3.3.2 release

      composer require -W ycloudyusa/yusaopeny:10.3.3.2
      
    • Run database updates

      ../vendor/drush/drush/drush updatedb -l $SITE_URL
      
  9. Address CKEditor5 Font Issue

    • Uninstall the existing CKEditor5 Font module

      uninstall ckeditor5_font
      
    • Require the latest beta version of CKEditor5 Font

      composer require 'drupal/ckeditor5_font:^1.1@beta'
      
    • Enable the CKEditor5 Font module

      ../vendor/drush/drush/drush en ckeditor5_font
      

Important Considerations

  • Backup: Always back up your site and database before performing any major upgrades.
  • Testing: Thoroughly test your site after each upgrade step on a staging environment before deploying to production.
  • Customizations: If you have made significant customizations to your site, consult with a Drupal developer to ensure a smooth upgrade process.
  • Drush Path: Adjust the ../vendor/drush/drush/drush path if your Drush installation is located elsewhere.
  • $SITE_URL: Replace $SITE_URL with the actual URL of your site.

Disclaimer: This use case provides a general outline for upgrading the YMCA Website Services Drupal distribution. Specific steps and commands may vary depending on your site’s configuration and any additional modules or customizations you have installed. Always refer to the official YMCA Website Services documentation and Drupal.org for the most up-to-date information and best practices.

56 - Upgrading to a new version of the distribution

Review a video about this document.

Before upgrading, please review these required version steps for your upgrade path.

Overview

Upgrade steps

Prepare dedicated environment for upgrade testing

Ensure you have a working computer or virtual machine with:

  • Ubuntu 20.04 (16.04, 18.04, or any decent Ubuntu LTS version) 64 bit
  • MySQL 5.7+ (8+ is preferred because of the performance improvements)
  • Apache 2.4 (or Nginx + php-fpm in case if you are fine with htaccess issues down the road)
  • PHP 8.1 (pre 8.1 could be an issue with some contrib modules)
  • Drush 12 || 10 || 11

The YMCA Website Services team maintains Vagrant preconfigured Virtualbox based virtual machine with OpenY. Feel free to use it to get a working virtual environment.

Your own YMCA Website Services instance should have a virtual machine injected into your site codebase. Just find Vagrantfile and proceed with vagrant up accordingly to the documentation.

Obtain local copy of your production site

You have to create a local copy of your site locally to be able to proceed with the upgrade.

For that:

  • Make a backup of your production database and copy it to your local machine
  • Make a copy of your production site codebase and copy it to your local machine
  • Ensure you have not manually removed Drupal modules in your database without the uninstallation step being executed! In this case you’ll need to return the module back to the codebase and uninstall it via Drupal Extend UI or Drush before running the next steps to upgrade YMCA Website Services.
  • Upgrade your site to latest Open Y - 9.2.11.3 See respective docs from Open Y documentation

Run command

In the same folder where your docroot is, run:

mv composer.json composer.json.bak || true
wget https://raw.githubusercontent.com/YCloudYUSA/yusaopeny-project/9.2.x/composer.json
composer update -W

The script above replaces your composer.json file, so it’s only applicable to websites that have the file unmodified.

If your composer.json file is modified, merge the changes manually. Essentially, the repositories section of the file is updated.

Update the site

Go to the docroot folder of your codebase and run:

drush updatedb

If updatedb fails…

you can use Drupal’s hook_update_dependencies API to change the order of running updates to eliminate issues. See this example.

Ensure commands above have finished with no error messages. The best way to check it is to run them one more time. If the next run shows:

$ drush updatedb
No database updates required                                                                                    [success]

You have almost 100% proven updates were executed correctly.

If loading the site fails…

you may receive an error like this:

Error: Class … not found in …

This happens due to Drupal not finding the renamed modules. To resolve this, manually clear the Drupal caches:

drush ev "drupal_flush_all_caches();"
drush cr

which should clear up the errors.

Visit OpenY upgrade tool dashboard

Review and revert or apply an updated version of the configs after the upgrade.

image

Check for regressions

In order to check for regressions during the upgrade, it is best to work with smoke tests. YMCA Website Services maintains the smoke tests database document you should use for the process.

Backup current state of the updated site

Use drush sql-dump or another backup tool to take a backup of the site in its current state.

Proceed with an update to next version until succeeded (Start from item 1)

57 - Videos

Video Tutorials

The YMCA Digital Services team maintains a YouTube channel with video tutorials for developers, content editors, evaluators, and more. Visit YouTube for the full list of content.

Playlists

58 - Virtual Y Configuration

Virtual Y predefined pages

Once Virtual Y installed system creates set of required Landing pages with predefined URLs. These pages are:

  • Virtual Y Landing page - /virtual-ymca
  • Virtual Y Login Landing page - /virtual-y-login

URLs to pages above then set as configuration values at /admin/openy/virtual-ymca.

Admin user is obligated to keep pages in the system or properly update configuration with new values to keep Virtual Y functionality working correctly.

Protecting Virtual Y Pages

If content editors modify the alias or remove the Virtual Y pages above, the VY site may break. Site administrators may want to add additional protections to the site to prevent editors from making those changes. We recommend Node Keep for this purpose:

  • Add node_keep to your repo with `composer require ‘drupal/node_keep’
  • Enable the module in Drupal
  • Edit each of the pages above and set the Node Keep options as you wish to protect the pages

Screenshot displaying Node Keep options

Virtual Y Log module

Virtual Y Log module can be configured via configuration files. Available settings:

  • activity_granularity_interval: Default value 600 - sets the interval in Seconds to track user activity on the site
  • archiver_enabled: default value true - enable / disable activity logs archiver cron execution
  • archiver_store_period: default value 1 year - set the period when activity logs will be collected and placed to same archive. This value should be set to as Relative Date/Time PHP string, e.g. 1 week, 2 months, 1 year, etc.

59 - Website Services Terms of Use

Version 2.1, December 2022

This is a free service provided by YUSA (“we,” “us,” and “our”) for users in the YMCA community (“users,” “you,” and “your”). By using the Website Services distribution repository, you agree to these Terms of Use.

We reserve the right to modify or discontinue, temporarily or permanently any services or the Terms of Use at any time, with or without prior notice to users. YUSA is not liable for any damage to any user or other third party that may result from any such modification, suspension or discontinuance of the service or of the Terms of Use.

Downloading

YUSA is not responsible for the content maintained in the repository. Any material downloaded or otherwise obtained through your use of our services is done at your own discretion and risk, and you will be solely responsible for any damage to your computer system or loss of data that results from the download of any such material. You agree that we have no responsibility or liability for the deletion of or the failure to store or to transmit, any content or communication maintained by the service. We retain the right to create limits on use and storage at our sole discretion at any time with or without notice.

We are not responsible for the content, data, or actions of third parties, and you release YUSA, our directors, officers, employees, and agents from any claims and damages, known and unknown, arising out of or in any way connected with any claim you have against any such third parties. No advice or information, whether oral or written, obtained by you from us or through or from our services creates any warranty not expressly stated in these Terms of Use.

All code downloaded from Website Services distribution is based on the Drupal® code base, which is subject to the terms of the Drupal license ( www.drupal.org). Website Services distribution code is a derivative work of Drupal and any distribution must be under the terms of the GNU General Public License version 2 or later versions.

Unless otherwise stated, all content (excluding code), including user-generated content, such as comments and discussions on the Website Services distribution web site, is licensed under Creative Commons License, Attribution-ShareAlike 2.0.

Contributing

The term “contribution” means any source code, object code, patch, tool, sample, graphic, specification, manual, documentation, comments or any other content posted or submitted by you to Website Services distribution. We welcome proposed contributions, however, all contributions are subject to review and approval, and potential modification, before inclusion in a release as part of Website Services distribution.

It is your responsibility to obtain appropriate licensing and attribution for content that you submit to Website Services distribution. Content without appropriate licensing or attribution will be removed.

You represent and warrant that:

  • Each contribution that you submit is an original work of authorship and you can legally grant the rights set out in these Terms of Use;

  • To the best of your knowledge, each contribution will not violate any third party’s copyrights, trademarks, patents, or other intellectual property rights;

  • Each contribution shall be in compliance with U.S. export control laws and other applicable export and import laws.

You agree to notify us if you become aware of any circumstance which would make any of the foregoing representations inaccurate in any respect.

All code must comply with the reasonable standards issued by Website Services distribution, including architecture and security protocols. All code submitted to the repository that is a derivative work must be GPLv2+ compatible and will automatically be redistributed as GPLv2+.

YUSA in its sole discretion will review, modify and determine whether to include code in its next release. We can refuse or remove any contributions at our discretion and without prior notice.

Disclaimer

All content is provided “as is,” without any warranty of any kind, either expressed or implied, including, but not limited to, the implied warranties of merchantability, fitness for a particular purpose and non-infringement; (ii) YUSA makes no other warranty that its services will meet your requirements, be safe, secure, uninterrupted, timely, accurate, or error-free, or that your information will be secure; and (iii) the entire risk as to the quality and performance of the content is with you.

Limit of Liability

In no event will YUSA, its affiliates or their licensors, service providers, employees, agents, officers, or directors be liable for any indirect, special, incidental, consequential or punitive damages, including but not limited to loss of revenue, loss of profits, loss of business or anticipated savings, loss of goodwill, and whether caused by tort (including negligence), breach of contract or otherwise, even if foreseeable. The foregoing does not affect any liability which cannot be excluded or limited under applicable law.

Copyright DMCA Notice

If a user or other third party believes that its content has been copied in a way that constitutes copyright infringement, that user or third party should provide YUSA with the following information: (a) an electronic or physical signature of the person authorized to act on behalf of the owner of the copyright

interest; (b) a description of the copyrighted work that has been infringed; (c) a description of where the allegedly infringing material is located; (d) the affected user or third party’s address, telephone number and email address; (e) a statement by the affected user or third party that he or she has a good faith belief that the disputed use is not authorized by the copyright owner, its agent or the law; and (f) a statement by the affected user or third party, under penalty of perjury, that the above information is accurate and that such user or third party is the copyright owner or is otherwise authorized to act on the copyright owner’s behalf. Please report any alleged copyright infringements to https://ymca.org.

Venue and Governing Law This Agreement shall be governed by, and construed in accordance with, the laws of the State of Minnesota, without reference to conflicts of laws principles. The parties agree that the federal and state courts in the county of Hennepin, Minnesota will have exclusive jurisdiction and venue under this Agreement, and each party hereby agrees to submit to such jurisdiction exclusively.