diff --git a/.github/workflows/docker-base.yml b/.github/workflows/docker-base.yml index 9a25b7a61..beee770d7 100644 --- a/.github/workflows/docker-base.yml +++ b/.github/workflows/docker-base.yml @@ -13,10 +13,10 @@ jobs: packages: write strategy: matrix: - php_version: [8.2, 8.3, 8.4] + php_version: [8.2, 8.3, 8.4, 8.5] steps: - name: Checkout - uses: actions/checkout@v5 + uses: actions/checkout@v6 - name: Set up QEMU uses: docker/setup-qemu-action@v3 @@ -26,7 +26,7 @@ jobs: uses: docker/setup-buildx-action@v3 - name: Login to Docker Hub - uses: docker/login-action@v3.5.0 + uses: docker/login-action@v3 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} @@ -45,6 +45,7 @@ jobs: org.opencontainers.image.vendor=BMLT org.opencontainers.image.created={{date 'YYYY-MM-DDTHH:mm:ssZ'}} org.opencontainers.image.version=${{ matrix.php_version }} + org.opencontainers.image.revision=${{ github.sha }} php.version=${{ matrix.php_version }} - name: Build and push Base @@ -66,7 +67,7 @@ jobs: packages: write steps: - name: Checkout - uses: actions/checkout@v5 + uses: actions/checkout@v6 - name: Set up QEMU uses: docker/setup-qemu-action@v3 @@ -76,7 +77,7 @@ jobs: uses: docker/setup-buildx-action@v3 - name: Login to Docker Hub - uses: docker/login-action@v3.1.0 + uses: docker/login-action@v3 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ded5c2c14..d190e1953 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -37,10 +37,10 @@ jobs: - name: php ${{ matrix.php }} 🐘 id: setup-php - uses: shivammathur/setup-php@2.35.4 + uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php }} - tools: composer:v2.8.8 + tools: composer:v2.8.12 - name: make composer 🎼 run: | @@ -58,7 +58,7 @@ jobs: - name: Send coverage data to codecov.io 📀 if: matrix.db == 'latest' && matrix.php == '8.4' - uses: codecov/codecov-action@v5.5.0 + uses: codecov/codecov-action@v5 with: files: src/coverage.xml token: ${{ secrets.CODECOV_TOKEN }} @@ -69,10 +69,10 @@ jobs: - name: checkout 🛒 uses: actions/checkout@v5 - - name: node 20 ❇️ - uses: actions/setup-node@v4.4.0 + - name: node 22 ❇️ + uses: actions/setup-node@v6 with: - node-version: 20 + node-version: 22 - name: make npm ♦️ run: | @@ -98,32 +98,28 @@ jobs: contents: write steps: - name: Checkout 🛒 - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: php 8.2 🐘 id: setup-php - uses: shivammathur/setup-php@2.35.4 + uses: shivammathur/setup-php@v2 with: php-version: '8.2' - tools: composer:v2.8.8 + tools: composer:v2.8.12 - name: make composer 🎼 run: | make composer - - name: setup node 20 ❇️ - uses: actions/setup-node@v4.4.0 + - name: setup node 22 ❇️ + uses: actions/setup-node@v6 with: - node-version: 20 + node-version: 22 - name: make frontend 🐥 run: | make frontend - - name: make crouton 🍞 - run: | - make crouton - - name: Write .env with APP_VERSION and COMMIT_SHA 🧃 shell: bash run: | @@ -137,7 +133,7 @@ jobs: make zip - name: Configure S3 AWS Credentials 🪪 - uses: aws-actions/configure-aws-credentials@v4 + uses: aws-actions/configure-aws-credentials@v5 with: role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/github-actions/gh-ci-s3-artifact role-session-name: gh-actions @@ -149,7 +145,7 @@ jobs: - name: Configure AWS Credentials 🪪 if: contains(github.ref_name, 'main') || contains(github.ref_name, 'unstable') - uses: aws-actions/configure-aws-credentials@v4 + uses: aws-actions/configure-aws-credentials@v5 with: role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/github-actions/gh-ci-tf-bmlt-rs role-session-name: gh-actions-bmlt @@ -182,7 +178,7 @@ jobs: echo "RELEASE_TYPE=${RELEASE_TYPE}" >> $GITHUB_ENV - name: Create Release 🎉 - uses: ncipollo/release-action@v1.18.0 + uses: ncipollo/release-action@v1 if: github.ref_type == 'tag' with: artifacts: "build/bmlt-server.zip" @@ -208,7 +204,7 @@ jobs: uses: actions/checkout@v5 - name: Configure AWS Credentials 🪪 - uses: aws-actions/configure-aws-credentials@v4 + uses: aws-actions/configure-aws-credentials@v5 with: role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/github-actions/gh-ci-tf-bmlt-rs role-session-name: gh-actions-bmlt diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 16054c191..2631dbde2 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -29,11 +29,11 @@ jobs: options: --health-cmd="${{ (matrix.db == 'latest') && 'mariadb-admin' || 'mysqladmin' }} ping" --health-interval=5s --health-timeout=2s --health-retries=3 steps: - name: checkout 🛒 - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: php ${{ matrix.php }} 🐘 id: setup-php - uses: shivammathur/setup-php@2.35.4 + uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php }} tools: composer:v2.6.5 @@ -58,10 +58,10 @@ jobs: - name: checkout 🛒 uses: actions/checkout@v5 - - name: node 20 ❇️ - uses: actions/setup-node@v4.0.0 + - name: node 22 ❇️ + uses: actions/setup-node@v6 with: - node-version: 20 + node-version: 22 - name: make npm ♦️ run: | diff --git a/CHANGELOG.md b/CHANGELOG.md index a02277a07..89609698d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,42 @@ -## 4.0.0 (UNRELEASED) -* Added new user interface implemented in Svelte. This includes a brand-new UI code base and various improvements. It is mostly backward compatible, except as noted here: +## 4.1.0 (UNRELEASED) +* Settings Management UI: + * All server settings (except database credentials) are now fully configurable through the + Admin UI's Settings page. Settings are stored in the database and can also be managed via the Admin API (/api/v1/settings). + * A migration was added to automatically seed settings from legacy `auto-config.inc.php` file on upgrade. +* Fix location map errors when auto geocoding is disabled. +* Fix duplicate format keys in the initial migrations schema and in existing databases + +## 4.0.4 (November 26, 2025) +* Modified the UI to hide the New Meeting button and show a helpful message when a user does not have editing privileges on any service bodies. +* Fixed an issue that prevented users from logging in to Yap servers that use this BMLT server. + +## 4.0.3 (November 23, 2025) +* Fixed an issue that prevented the UI from loading on servers with a `RewriteOptions inherit` configuration. +* Fixed `$format_lang_names` setting to work with the new UI. +* Fixed a geocoding issue -- if the county and/or zip code is automatically computed by the geocoder, we don't want to feed old and possibly incorrect values to the geocoder if the user edits an address. +* Fixed problems with format key validation. +* Added Portuguese translations. +* Strip legacy `#@-@#` separator from custom field values in UI display. + +## 4.0.2 (November 11, 2025) +* Added Italian translations. +* Updated German translations. +* Fix favicon. +* Mask visibility=1 fields with asterisks in GetChanges json_data for unauthorized users. +* Fixed an issue where a service body couldn't be edited if one of its meeting editor users had been deleted. +* Fixed admin routes failing to load when accessed via direct URL or bookmark. +* Added database migrations to trim user fields whitespace and to remove nonexistent users from service body assignments. + +## 4.0.1 (November 5, 2025) +* Fixed longitude/latitude fields to be read-only when auto-geocoding is enabled + +## 4.0.0 (November 4, 2025) +* Added new user interface implemented in Svelte. This includes a brand-new UI code base and various improvements, including support for mobile devices and dark mode. It is mostly backward compatible, except as noted here: - Dropped support for the installer wizard -- see `installation/README.md` for new directions. - Deprecated the auto-config parameter `$default_minute_interval` (now just set to 5 minutes). +* The new UI is mobile-friendly and includes dark mode support. +* Added newly rewritten semantic workshop. +* Added new `$bmlt_notice` setting for `auto-config.inc.php` to display custom notices on the login screen. Example: `$bmlt_notice = 'We've upgraded the BMLT to 4.0.0 with a new interface! Please report any issues to bmlt@example.org';` * Fixed a bug that prevented the NAWS Export from working with newer versions of MySQL. ## 3.1.2 (May 2, 2025) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3713f05d9..83bfba6bb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -3,65 +3,68 @@ For general information about BMLT, including ways to contribute to the project, please see [the BMLT website](https://bmlt.app). -This file contains information specifically about how to set up a development environment to work on the server. -We want the server code (as well as code for the other project core elements) to continue to be of high quality, so -prospective developers should have a solid grounding in good software engineering practice. In other words, making -changes to the server code with the intent to contribute them back to -the main repository wouldn't be the best place to start for folks new to software development -- there are, on -the other hand, lots of other parts of the project that could very much use your time and energy! (An exception is -that we do frequently need fluent speakers of languages other than English to translate localization strings -- even -if the initial translation has already been done, there are often new strings added in subsequent development work -that need translation.) - -There are various ways you can set up your development environment; in the directions here we use -[Docker](https://www.docker.com). If you don't have them already, clone the server repo from github, and install -[Docker Desktop](https://www.docker.com/products/docker-desktop). The make file assumes docker-compose v2. - -## Running the server under docker -1. You will need to make sure you are using docker-compose v2. You can do this by opening the docker dashboard and going -to preferences then general then scroll to the bottom and check the box that says `Use Docker Compose V2`, then hit apply & -restart. -1. Copy `docker/docker-compose.dev.yml.example` to `docker/docker-compose.dev.yml` and edit it to set the `GKEY` variable to your google api key. -1. Run the command `make dev` in the top-level `bmlt-server` directory. If something isn't working (for example, +This file contains information specifically about how to set up a development environment for work on the server. There are various ways you can do this; in the directions here we use +[Docker](https://www.docker.com). If you don't have them already, clone the +[BMLT server repo](https://github.com/bmlt-enabled/bmlt-server) from github, and install +[Docker Desktop](https://www.docker.com/products/docker-desktop). These directions were tested with Docker Desktop v4.53.0. + +## Running the Server under Docker +1. If you want to use Google Maps for displaying meeting locations, copy `docker/docker-compose.dev.yml.example` to `docker/docker-compose.dev.yml` and edit it to set the `GOOGLE_API_KEY` variable to your google api key. If you want to use OpenStreetMap, omit this step. You can also provide values for other environment variables using this file (see below). +2. Run the command `make dev` in the top-level `bmlt-server` directory. If something isn't working (for example, mising packages), try running `make clean` first and then `make dev`. -1. Browse to `http://localhost:8000/main_server/`. -1. Login with username "serveradmin" and password "CoreysGoryStory". -1. When finished, exit by pressing ctrl+c. You may also wish to delete the containers in the Docker Dashboard. +3. Browse to `http://localhost:8000/main_server/`. +4. Login with username "serveradmin" and password "CoreysGoryStory". +5. When finished, exit by pressing ctrl+c in the terminal window where you ran `make dev`. You may also wish to delete the containers in the Docker Dashboard. -### Supported environment variables -This is an example `docker-compose.dev.yml` file. The value for each of these variables, on start of the container, is automatically -written to the appropriate line in `auto-config.inc.php`. -``` -version: '3' +### Environment Variables and Settings + +When running a production server, there is a file `auto-config.inc.php` that is used to initialize a set of environment variables used by the server. Other server settings are read from a table in the database. + +For development work, Docker takes care of initializing these environment variables. You can also specify other server settings that will override the values in the database. This is done by adding key/value pairs to the file `docker/docker-compose.dev.yml`. The sample file `docker/docker-compose.dev.yml.example` has just one variable listed (`GOOGLE_API_KEY` for the Google API key). You can add others as needed. The keys should be in SCREAMING_SNAKE_CASE. See the `SETTING_DEFAULTS` constant in `src/database/migrations/2025_11_20_133800_seed_settings_from_legacy_config.php` for a list of possibilities. There are also a few database options: `DB_PREFIX`, `DB_DATABASE`, `DB_USERNAME`, `DB_PASSWORD`, and `DB_HOST`. Of these `DB_PREFIX` is probably the only one you might want to override. + +Server settings that are overridden by entries in `docker/docker-compose.dev.yml` will show up correctly in the Server Settings pane in the UI, but won't necessarily be reflected in the `settings` table in the database. However, if you make a change to the settings in the UI and save, then all the values (including ones from entries in `docker/docker-compose.dev.yml`) will be written to the database. +### Switching PHP Versions + +To test with a different PHP version, add this to `docker/docker-compose.dev.yml`: +```yaml services: bmlt: - environment: - GKEY: '' - DB_DATABASE: rootserver - DB_USER: rootserver - DB_PASSWORD: rootserver - DB_HOST: db - DB_PREFIX: na - NEW_UI_ENABLED: 'true' - AGGREGATOR_MODE_ENABLED: 'false' + build: + args: + PHP_VERSION: 8.4 ``` -## Developing the New UI -The new UI is developed using [Svelte](https://svelte.dev/), and the code is located in the `resources/js` directory. +Then rebuild without cache: +```bash +docker compose -f docker/docker-compose.yml -f docker/docker-compose.dev.yml build --no-cache bmlt +make dev +``` -You can enable the new UI in the docker container by setting the `NEW_UI_ENABLED` environment variable to `'true'` in `docker/docker-compose.dev.yml`. +## Loading a Different Sample Database + +If your database uses a table prefix other than `na` (say `myprefix`), add this line to `docker/docker-compose.dev.yml`: +``` +DB_PREFIX: 'myprefix' +``` +Then use the following command to load your database: +``` +docker exec -i docker-db-1 sh -c 'exec mariadb -uroot -prootserver rootserver' < mydb.sql +``` + +## UI Development +The UI is now written using [Svelte](https://svelte.dev/), and the code is located in the `resources/js` directory. (The previous UI has now been removed from the current code base.) To install the UI's dependencies, run the `npm install` command from the `src` directory. When working on the UI, you'll need to have the [Vite](https://vitejs.dev/) dev server running. To start the dev server, run `npm run dev` from the `src` directory. While the dev server is running, the UI is served out of the `resources/js` directory instead of the normal `public` directory, and [hot module replacement](https://vitejs.dev/guide/features.html#hot-module-replacement) is enabled. -### Debugging the New UI -This assumes you are using [VS Code](https://code.visualstudio.com) to develop the new UI. +### Debugging the UI +This assumes you are using [VS Code](https://code.visualstudio.com) to develop the UI. -#### Debugging the Browser -First, follow the instructions above for running the server under Docker with `NEW_UI_ENABLED` set to `'true'`. This mostly just involves running `make dev`. +#### Debugging Using a Browser +First, follow the instructions above for running the server under Docker. This mostly just involves running `make dev`. Then, create `.vscode/launch.json` with a `chrome` debug configuration: @@ -82,75 +85,187 @@ Then, create `.vscode/launch.json` with a `chrome` debug configuration: You should now be able to set breakpoints, launch this debug configuration, and step through the code. -#### Debugging the Tests +#### Debugging Tests This works exactly as described in the [vitest documentation](https://v0.vitest.dev/guide/debugging.html). Set any breakpoints, launch a new JavaScript Debug Terminal, and run `npm run test`. -## Some useful `make` commands +## Developing with the TypeScript Client + +When developing Admin API features alongside the TypeScript client, you can use [npm link](https://docs.npmjs.com/cli/v11/commands/npm-link/) to work with both repositories locally without publishing to npm. + +### Prerequisites +Clone the BMLT TypeScript client repository: +```bash +git clone https://github.com/bmlt-enabled/bmlt-server-typescript-client.git +``` -- `make help` Describe all of the make commands. +### One-time Setup +1. Link the TypeScript client globally: + ```bash + cd /path/to/bmlt-server-typescript-client + npm link + ``` + +2. Link the client in the BMLT server frontend: + ```bash + cd /path/to/bmlt-server/src + npm link ../../bmlt-server-typescript-client + ``` + +### Development Workflow +After making API changes, regenerate the TypeScript client: + +1. Generate updated OpenAPI documentation: + ```bash + cd /path/to/bmlt-server + make generate-api-json + ``` + +2. Regenerate the TypeScript client: + ```bash + cd /path/to/bmlt-server-typescript-client + rm openapi.json + make generate + ``` + +This allows you to develop the API without changing your configs or imports. + +## Some Useful `make` Commands + +- `make help` Describe all the make commands. - `make clean` Clean the build by removing all build artifacts and downloaded dependencies. - `make docker` Builds the docker image. You really only need to run this when first getting set up or after a change has been made to the Dockerfile or its base image. - `make dev` Run the server under docker (see above). - `make bash` Open a bash shell on the container's file system. This will start in the directory `/var/www/html/main_server` -- `make mysql` Start the mysql command-line client with the database `rootserver`, which holds the server's tables. +- `make mysql` Start the mysql command-line client with the database `rootserver`, which holds the server's tables. (Well, actually it uses the MariaDB command-line client now rather than mysql, but the `make` command still has the old name.) - `make test` Run PHP tests. There are some additional commands as well; `make help` will list them. -## Loading a different sample database - -Use this command to replace the supplied test database with your own: -``` -docker exec -i docker-db-1 sh -c 'exec mariadb -uroot -prootserver rootserver' < mydb.sql -``` - -## Running tests +## Running PHP Tests Start the server using `make dev` (see above). Then in a separate terminal, run the tests using `make test`. -Somewhat annoyingly, `make test` will clobber your current database, so you'll need to restore it if you want to go -back to running the server. - ## Running lint You can run the linter by running `make lint` in the top-level directory. It doesn't work when xdebug is listening, so make sure xdebug is off first. -## Testing the install wizard -The Docker files automatically set up an `auto-config.inc.php` file for you. Usually this is great since it saves you -the bother of going through the install wizard each time you restart the server. However, if you want to test or -change the install wizard, you can start with the install wizard instead of the login screen by deleting this file. -Here are modified steps to do that. -1. Edit `docker-compose.dev.yml` to set your google maps api key, `GKEY: API_KEY`. -1. Run the command `make dev` in the top-level `bmlt-server` directory. -1. In another window, run `make bash` to open a bash shell accessing the container's file system. The shell should -start in the directory `cd /var/www/html/main_server`. -1. In the bash shell, `cd ..` to get to the parent directory, then `rm auto-config.inc.php`. -1. Leave the shell open so that you can check whether the installer generated a new `auto-config.inc.php` and if so what it contains. -1. Browse to `http://localhost:8000/main_server/`. -1. In the browser you will now be in the Install Wizard. Start by filling in the Database Connection Settings screen as follows. -``` -Database Type: mysql -Database Host: db -Table Prefix: na2 -Database Name: rootserver -Database User: rootserver -Database Password: rootserver -``` -Note that the Database Host is `db` rather than the usual `localhost`. If you start with the install wizard, normally -you need an empty database, but the `rootserver` database already contains sample data. A convenient alternative to dropping -and (re) creating `rootserver` is to use the provided `rootserver` database, and to change the Table Prefix to `na2`, as -above. If you need to run the installer again, just use a new Table Prefix each time (`na3` etc). - -Finally, as with the earlier directions, when finished exit by pressing ctrl+c or by running `docker-compose down`. - -## To debug in IntelliJ or PhpStorm (see screenshots below for more detail) - -1. Open IntelliJ Preferences. Go to `Languages & Frameworks -> PHP -> Debug`. Under the `Xdebug` section, set the `Debug port` to `10000,9003`. Close IntelliJ Preferences. ![image](docker/img/intellij-prefs-xdebug.png) -1. Add a new `PHP Remote Debug` debug configuration. -1. In the new debug configuration, make click the three dots `...` next to the Server field, and add a new Server. Set the server's `Host` to `0.0.0.0`, and set the `Port` to `8000`. Check the `Use path mappings` checkbox, and set the `Absolute path on the server` for the `Project files` to `/var/www/html/main_server`. ![image](docker/img/add-debug-server.png) -1. Check `Filter debug connection by IDE key` and set the `IDE Key(session id)` to `ROOT_SERVER_DEBUG`. ![image](docker/img/final-debug-configuration.png) -1. To start debugging, select your new debug configuration and click the `Start Listening for PHP Debug Connections` icon. ![image](docker/img/start-listening.png) -1. Then, click the `Debug` icon to open your web browser and start the XDebug session. ![image](docker/img/debug.png) -1. Then, browse to `http://0.0.0.0:8000/main_server/` +## Utility Commands to Help with Localization +The strings that the UI displays are localized using files in the `src/resources/js/lang` directory. So if you add a new string, normally the programmer would need to add it to 11 or more files (one file per language). There are some utility commands to make this easer. If you are running under Docker, a convenient way to run them is to open a bash shell using `make bash`, connect to the `src` directory, and run the desired command. + +### Adding a new key/value pair or updating an existing one +This adds a new key/value pair to all language files, respecting alphabetical order. For languages other than English, the new key/value pair will also have a comment `// TODO: translate`. +```` +php artisan translation:add meetingName "Meeting Name" +```` +To update an existing key use `--force`. +```` +php artisan translation:add cancel "Cancelled" --force +```` + +### Deleing a Key/Value Pair +This deletes a key and its value from all language files. +```` +php artisan translation:delete oldKey +```` + +### Updating the Translations for One Language from a Spreadsheet +A convenient starting point for the spreadsheet file is to use the button `Download Translations Spreadsheet` under the Administration tab. +```` +php artisan translation:update-from-spreadsheet /path/to/italian-translations.xlsx it +```` + +## Adding a New Language to the Server + +To add a new language (for example, Norwegian, which has [ISO 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639_language_codes) code `no`): + +### Backend Translation Files + +1. Copy the English translation directory: + ```bash + cp -r src/lang/en/ src/lang/no/ + ``` + +2. Edit `src/lang/no/language_name.php` to set the native language name: + ```php + 'Norsk', + ]; + ``` + +3. Translate the strings in the other PHP files (`main_prompts.php`, `change_detail.php`, `change_type.php`, `weekdays.php`, etc.). + +### Frontend Translation Files + +1. Copy the English translation file: + ```bash + cp src/resources/js/lang/en.ts src/resources/js/lang/no.ts + ``` + +2. Translate the strings in the file `src/resources/js/lang/no.ts` and rename the two constants that it exports: + `enYupLocale` => `noYupLocale`, `enTranslations` => `noTranslations`. + + +3. Export the new language in `src/resources/js/lang/index.ts`: + ```typescript + export { noTranslations, noYupLocale } from './no'; + ``` + +4. Import and add the new language to `src/resources/js/stores/localization.ts`: + - Add to imports (maintain alphabetical order): + ```typescript + noTranslations, + noYupLocale, + ``` + - Add to the `strings` object (maintain alphabetical order): + ```typescript + no: noTranslations, + ``` + - Add to the `yupLocales` object (maintain alphabetical order): + ```typescript + no: noYupLocale, + ``` + +### Format Translations + +The server will actually run without any format translations for the new language, but you will almost certainly want to add some to provide a reasonable experience for users and service body administrators. There are two options for adding format translations for the new language: +1. add them using a database migration +2. add them by logging in as the server admin and using the editor available on the Formats tab + +Option 1 puts the format translations into the code base, and is how all the formats that come with a fresh out-of-the-box server are defined. + +Option 2 is much simpler -- just use the format translation editor in the UI -- but they won't be in the code base and someone who spins up a new server in your new language won't get them automatically. You can also do some of both: start with a set of basic format translations defined using a database migration, and then add some additional ones using the UI. + +For historical reasons, the meeting's venue type (in-person, hybrid, or virtual) is specified in the server database using the `HY` (hybrid) and `VM` (virtual meeting) formats. The UI for service body administrators doesn't expose these to the administrator however; they get set using the Venue Type menu on the meeting editor Location tab. `TC` (Temporarily Closed) has been deprecated -- it was used a lot during the pandemic -- but you may still encounter it if you start with a database containing some older data. However, these formats **are** visible in crouton and bread for hybrid, virtual, or temporarily closed meetings, so you should provide translations for them. + +The migration `src/database/migrations/1902_01_01_000000_create_initial_schema.php` includes translations for the formats shipped with the server. You can use these as suggestions for other translations you might want to provide for the new language. + +## Debugging in IntelliJ or PhpStorm + +See screenshots below for more detail. + +1. Open IntelliJ Settings. Go to `Languages & Frameworks -> PHP -> Debug`. Under the `Xdebug` section, set the `Debug port` to `10000,9003`. Click OK and close IntelliJ Preferences. + +![image](docker/img/intellij-prefs-xdebug.png) + +2. Pick `Run -> Edit Configurations...` Add a new `PHP Remote Debug` debug configuration. +3. In the new debug configuration, check `Filter debug connection by IDE key`. Click the three dots `...` next to the Server field, and add a new Server. Set the server's `Host` to `0.0.0.0`, and set the `Port` to `8000`. Check the `Use path mappings` checkbox, and set the `Absolute path on the server` for the `src` directory under `Project files` to `/var/www/html/main_server`. Click OK. + + ![image](docker/img/add-debug-server.png) + +4. Back in the debug configuration, set the `IDE Key(session id)` to `ROOT_SERVER_DEBUG`. + +![image](docker/img/final-debug-configuration.png) + +5. To start debugging, select your new debug configuration and click the `Start Listening for PHP Debug Connections` icon. + +![image](docker/img/start-listening.png) + +6. Then, click the `Debug` icon to open your web browser and start the XDebug session. + +![image](docker/img/debug.png) + +7. Finally, browse to `http://0.0.0.0:8000/main_server/` diff --git a/Makefile b/Makefile index eb9ee9ef6..2bf1e5e57 100644 --- a/Makefile +++ b/Makefile @@ -2,10 +2,8 @@ COMMIT := $(shell git rev-parse --short=8 HEAD) BASE_IMAGE := bmltenabled/bmlt-server-base BASE_IMAGE_TAG := 8.2 BASE_IMAGE_BUILD_TAG := $(COMMIT)-$(shell date +%s) -CROUTON_JS := src/public/client_interface/html/croutonjs/crouton.js SEMANTIC_HTML := src/public/semantic/index.html TIMEZONE_ASSETS := src/public/timezones-1970.geojson.index.json -LEGACY_STATIC_FILES := src/public/local_server/styles.css VENDOR_AUTOLOAD := src/vendor/autoload.php NODE_MODULES := src/node_modules/.package-lock.json FRONTEND := src/public/build/manifest.json @@ -19,14 +17,14 @@ ifeq ($(CI)x, x) NPM_FLAG := install COMPOSER_PREFIX := docker run --pull=always -t --rm -v '$(shell pwd)':/code -w /code $(BASE_IMAGE):$(BASE_IMAGE_TAG) LINT_PREFIX := docker run -t --rm -v '$(shell pwd)':/code -w /code/src $(IMAGE):$(TAG) - TEST_PREFIX := docker run -e XDEBUG_MODE=coverage,debug -t --rm -v '$(shell pwd)/src:/var/www/html/main_server' -v '$(shell pwd)/docker/test-auto-config.inc.php:/var/www/html/auto-config.inc.php' -w /var/www/html/main_server --network host $(IMAGE):$(TAG) + TEST_PREFIX := docker run -e XDEBUG_MODE=coverage,debug -t --rm -v '$(shell pwd)/src:/var/www/html/main_server' -w /var/www/html/main_server --network host $(IMAGE):$(TAG) ifneq (,$(wildcard docker/docker-compose.dev.yml)) EXTRA_DOCKER_COMPOSE_ARGS := -f docker/docker-compose.dev.yml endif else DOCKERFILE := Dockerfile IMAGE := bmltenabled/bmlt-server - TAG := 3.0.0-$(COMMIT) + TAG := 4.0.0-$(COMMIT) ifeq ($(strip $(GITHUB_REF_NAME)),main) TAG := latest endif @@ -49,15 +47,6 @@ help: ## Print the help documentation $(VENDOR_AUTOLOAD): $(COMPOSER_PREFIX) composer install --working-dir=src $(COMPOSER_ARGS) -$(CROUTON_JS): - curl -sLO https://github.com/bmlt-enabled/crouton/releases/latest/download/croutonjs.zip - mkdir -p src/public/client_interface/html/croutonjs - unzip croutonjs.zip -d src/public/client_interface/html/croutonjs - rm -f croutonjs.zip - rm -f src/public/client_interface/html/croutonjs/*.html - rm -f src/public/client_interface/html/croutonjs/*.json - rm -rf src/public/client_interface/html/croutonjs/examples - $(SEMANTIC_HTML): curl -sLO https://github.com/bmlt-enabled/semantic-workshop/releases/latest/download/semantic-workshop.zip mkdir -p src/public/semantic @@ -74,26 +63,29 @@ $(NODE_MODULES): $(FRONTEND): $(NODE_MODULES) cd src && npm run build -$(LEGACY_STATIC_FILES): - rsync -a -m \ - --include='**/*.js' \ - --include='**/*.css' \ - --include='**/*.png' \ - --include='**/*.svg' \ - --include='**/*.ttf' \ - --include='**/*.woff' \ - --include='**/*.woff2' \ - --include='**/*.eot' \ - --include='**/*.json' \ - --include='**/*.gif' \ - --include='*/' \ - --exclude='*' \ - src/legacy/ src/public - -$(ZIP_FILE): $(VENDOR_AUTOLOAD) $(FRONTEND) $(CROUTON_JS) $(SEMANTIC_HTML) $(TIMEZONE_ASSETS) $(LEGACY_STATIC_FILES) +$(ZIP_FILE): $(VENDOR_AUTOLOAD) $(FRONTEND) $(SEMANTIC_HTML) $(TIMEZONE_ASSETS) mkdir -p build cp -r src build/main_server - cd build && zip -r $(shell basename $(ZIP_FILE)) main_server -x main_server/node_modules/\* + cd build && zip -r $(shell basename $(ZIP_FILE)) main_server \ + -x main_server/.gitattributes \ + -x main_server/.gitignore \ + -x main_server/.nvmrc \ + -x main_server/.phpcs.xml \ + -x main_server/.phpstan.neon \ + -x main_server/app.html \ + -x main_server/coverage.xml \ + -x main_server/eslint.config.js \ + -x main_server/node_modules/\* \ + -x main_server/package.json \ + -x main_server/package-lock.json \ + -x main_server/phpunit.xml \ + -x main_server/.phpunit.result.cache \ + -x main_server/prettier.config.js \ + -x main_server/resources/js/\* \ + -x main_server/svelte.config.js \ + -x main_server/tests/\* \ + -x main_server/tsconfig.json \ + -x main_server/vite.config.ts rm -rf build/main_server .PHONY: composer @@ -102,9 +94,6 @@ composer: $(VENDOR_AUTOLOAD) ## Runs composer install .PHONY: npm npm: $(NODE_MODULES) ## Runs npm install -.PHONY: crouton -crouton: $(CROUTON_JS) ## Installs crouton - .PHONY: semantic semantic: $(SEMANTIC_HTML) ## Installs semantic workshop @@ -119,7 +108,7 @@ zip: $(ZIP_FILE) ## Builds zip file .PHONY: docker docker: zip ## Builds Docker Image - docker build --pull --build-arg PHP_VERSION=$(BASE_IMAGE_TAG) -f docker/$(DOCKERFILE) . -t $(IMAGE):$(TAG) + docker build --pull --build-arg PHP_VERSION=$(BASE_IMAGE_TAG) --label "org.opencontainers.image.revision=$(COMMIT)" --label "org.opencontainers.image.created=$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')" -f docker/$(DOCKERFILE) . -t $(IMAGE):$(TAG) .PHONY: docker-push docker-push: ## Pushes docker image to Dockerhub @@ -149,7 +138,7 @@ coverage-serve: ## Serves HTML Coverage Report .PHONY: generate-api-json generate-api-json: ## Generates Open API JSON - $(LINT_PREFIX) php artisan l5-swagger:generate + $(TEST_PREFIX) php artisan l5-swagger:generate .PHONY: lint lint: ## PHP Lint @@ -169,7 +158,7 @@ phpstan: ## PHP Larastan Code Analysis .PHONY: docker-publish-base docker-publish-base: ## Builds Base Docker Image - docker buildx build --platform linux/amd64,linux/arm64/v8 -f docker/Dockerfile-base docker/ -t $(BASE_IMAGE):$(BASE_IMAGE_TAG) --push + docker buildx build --platform linux/amd64,linux/arm64/v8 --label "org.opencontainers.image.revision=$(COMMIT)" --label "org.opencontainers.image.created=$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')" -f docker/Dockerfile-base docker/ -t $(BASE_IMAGE):$(BASE_IMAGE_TAG) --push .PHONY: mysql mysql: ## Runs mysql cli in mysql container @@ -182,8 +171,6 @@ bash: ## Runs bash shell in apache container .PHONY: clean clean: ## Clean build rm -rf src/public/build - rm -rf src/public/client_interface - rm -rf src/public/local_server rm -rf src/public/semantic rm -rf src/node_modules rm -rf src/vendor diff --git a/docker/Dockerfile b/docker/Dockerfile index 6df2a3c2a..c6ff8e75d 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -11,9 +11,4 @@ RUN \ # Handle mod_dir redirect using X-Forwarded headers COPY docker/.htaccess /var/www/html/main_server/.htaccess -COPY docker/write-config.sh /tmp/write-config.sh -COPY docker/start-bmlt.sh /tmp/start-bmlt.sh -COPY docker/aggregator-initialize-database.sh /tmp/aggregator-initialize-database.sh -COPY docker/aggregator-import-servers.sh /tmp/aggregator-import-servers.sh - -CMD ["/bin/bash", "/tmp/start-bmlt.sh"] +CMD ["apachectl", "-D", "FOREGROUND"] diff --git a/docker/Dockerfile-base b/docker/Dockerfile-base index 8cd5f13d7..ee8e6a2d2 100644 --- a/docker/Dockerfile-base +++ b/docker/Dockerfile-base @@ -1,4 +1,4 @@ -FROM ubuntu:jammy +FROM ubuntu:noble ARG PHP_VERSION=8.2 @@ -60,7 +60,7 @@ RUN ln -sf /proc/self/fd/1 /var/log/apache2/access.log && \ RUN a2enmod rewrite # Disable default PHP modules -RUN for ver in 7.4 8.0 8.1 8.2 8.3 8.4; do \ +RUN for ver in 8.1 8.2 8.3 8.4 8.5; do \ if [ -f "/etc/apache2/mods-enabled/php$ver.conf" ] && [ "$ver" != "${PHP_VERSION}" ]; then \ a2dismod php$ver; \ fi; \ diff --git a/docker/Dockerfile-debug b/docker/Dockerfile-debug index e54998052..3f55d2a98 100644 --- a/docker/Dockerfile-debug +++ b/docker/Dockerfile-debug @@ -6,6 +6,9 @@ ENV PHP_INI_PATH=/etc/php/${PHP_VERSION}/apache2/php.ini ENV PHP_CLI_INI_PATH=/etc/php/${PHP_VERSION}/cli/php.ini ENV PHP_XDEBUG_ENABLED=1 +RUN echo "opcache.revalidate_freq=0" >> ${PHP_INI_PATH} +RUN echo "opcache.revalidate_freq=0" >> ${PHP_CLI_INI_PATH} + RUN echo "zend_extension=$(find /usr/lib/php/ -name xdebug.so)" >> ${PHP_INI_PATH} \ && echo "xdebug.mode=coverage,debug" >> ${PHP_INI_PATH} \ && echo "xdebug.client_port=9003" >> ${PHP_INI_PATH} \ @@ -22,9 +25,4 @@ RUN echo "zend_extension=$(find /usr/lib/php/ -name xdebug.so)" >> ${PHP_CLI_INI && echo "xdebug.log=/tmp/xdebug.log" >> ${PHP_CLI_INI_PATH} \ && echo "xdebug.idekey=ROOT_SERVER_DEBUG" >> ${PHP_CLI_INI_PATH} -COPY docker/write-config.sh /tmp/write-config.sh -COPY docker/start-bmlt.sh /tmp/start-bmlt.sh -COPY docker/aggregator-initialize-database.sh /tmp/aggregator-initialize-database.sh -COPY docker/aggregator-import-servers.sh /tmp/aggregator-import-servers.sh - -CMD ["/bin/bash", "/tmp/start-bmlt.sh"] +CMD ["apachectl", "-D", "FOREGROUND"] diff --git a/docker/aggregator-import-servers.sh b/docker/aggregator-import-servers.sh deleted file mode 100644 index 8f9362e23..000000000 --- a/docker/aggregator-import-servers.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash -set -o xtrace -set -e - -/bin/bash /tmp/write-config.sh -/usr/bin/php /var/www/html/main_server/artisan aggregator:ImportRootServers diff --git a/docker/aggregator-initialize-database.sh b/docker/aggregator-initialize-database.sh deleted file mode 100644 index bd2743c4a..000000000 --- a/docker/aggregator-initialize-database.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash -set -o xtrace -set -e - -/bin/bash /tmp/write-config.sh -/usr/bin/php /var/www/html/main_server/artisan aggregator:InitializeDatabase diff --git a/docker/auto-config.inc.php b/docker/auto-config.inc.php index 5e3d50bd9..58f71f31e 100644 --- a/docker/auto-config.inc.php +++ b/docker/auto-config.inc.php @@ -1,40 +1,5 @@ -79.793701171875, 'latitude' => 36.06575205170711, 'zoom' => 10 ); // This is the default map location for new meetings. -$comdef_distance_units = 'mi'; - -// Display settings: -$bmlt_title = 'BMLT Administration'; // This is the page title and heading for the main administration login page. -$banner_text = 'Administration Login'; // This is text that is displayed just above the login box on the main login page. - -// Miscellaneous settings: -$comdef_global_language ='en'; // This is the 2-letter code for the default root server localization (will default to 'en' -English, if the localization is not available). -$min_pw_len = 10; // The minimum number of characters in a user account password for this root server. -$number_of_meetings_for_auto = 10; // This is an approximation of the number of meetings to search for in the auto-search feature. The higher the number, the wider the radius. -$change_depth_for_meetings = 5; // This is how many changes should be recorded for each meeting. The higher the number, the larger the database will grow, as this can become quite substantial. -$default_duration_time = '1:00:00'; // This is the default duration for meetings that have no duration specified. -$g_enable_language_selector = TRUE; // Set this to TRUE (or 1) to enable a popup on the login screen that allows the administrator to select their language. -$g_enable_email_contact = FALSE; // If this is TRUE (or 1), then this will enable the ability to contact meeting list contacts via a secure email form. - -// These are 'hard-coded,' but can be changed later. - -// These reflect the way that we handle contact emails. - -$include_service_body_admin_on_emails = FALSE; // If this is TRUE (or 1), then any emails sent using the meeting contact will include the Service Body Admin contact for the meeting Service body (ignored, if $g_enable_email_contact is FALSE). - -$include_every_admin_on_emails = FALSE; // If this is TRUE (or 1), then any emails sent using the meeting contact will include all Service Body Admin contacts (including the Server Administrator) for the meeting (ignored, if $g_enable_email_contact or $include_service_body_admin_on_emails is FALSE). - - -$time_format = 'g:i A'; // The PHP date() format for the times displayed. -$change_date_format = 'g:i A, n/j/Y'; // The PHP date() format for times/dates displayed in the change records. -$admin_session_name = 'BMLT_Admin'; // This is merely the 'tag' used to identify the BMLT admin session. -$g_enable_semantic_admin = TRUE; -$default_minute_interval = 5; // This sets the minutes interval for Start Time and Duration. diff --git a/docker/bmlt.env b/docker/bmlt.env deleted file mode 100644 index c4e81bb09..000000000 --- a/docker/bmlt.env +++ /dev/null @@ -1,8 +0,0 @@ -GKEY= -DB_DATABASE=rootserver -DB_USER=rootserver -DB_PASSWORD=rootserver -DB_HOST=db -DB_PREFIX=na -NEW_UI_ENABLED=false -AGGREGATOR_MODE_ENABLED=false diff --git a/docker/docker-compose.dev.yml.example b/docker/docker-compose.dev.yml.example index 81cdffe78..2113bf24c 100644 --- a/docker/docker-compose.dev.yml.example +++ b/docker/docker-compose.dev.yml.example @@ -1,5 +1,4 @@ services: bmlt: environment: - GKEY: '' - NEW_UI_ENABLED: 'false' + GOOGLE_API_KEY: '' diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 4a65d669c..b845689ef 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -8,11 +8,13 @@ services: - PHP_VERSION=${PHP_VERSION:-8.2} ports: - "8000:8000" - env_file: - - bmlt.env environment: APP_DEBUG: "true" DB_HOST: db + DB_DATABASE: rootserver + DB_USERNAME: rootserver + DB_PASSWORD: rootserver + DB_PREFIX: na depends_on: - db volumes: diff --git a/docker/start-bmlt.sh b/docker/start-bmlt.sh deleted file mode 100644 index 5046e8074..000000000 --- a/docker/start-bmlt.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash -set -o xtrace -set -e - -/bin/bash /tmp/write-config.sh -apachectl -D FOREGROUND diff --git a/docker/test-auto-config.inc.php b/docker/test-auto-config.inc.php deleted file mode 100644 index 2fbc399d3..000000000 --- a/docker/test-auto-config.inc.php +++ /dev/null @@ -1,2 +0,0 @@ -> /var/www/html/auto-config.inc.php -fi - -if [ ! -z $DB_DATABASE ] -then - echo "\$dbName = \"$DB_DATABASE\";" >> /var/www/html/auto-config.inc.php -fi - -if [ ! -z $DB_USER ] -then - echo "\$dbUser = \"$DB_USER\";" >> /var/www/html/auto-config.inc.php -fi - -if [ ! -z $DB_PASSWORD ] -then - echo "\$dbPassword = \"$DB_PASSWORD\";" >> /var/www/html/auto-config.inc.php -fi - -if [ ! -z $DB_HOST ] -then - echo "\$dbServer = \"$DB_HOST\";" >> /var/www/html/auto-config.inc.php -fi - -if [ ! -z $DB_PREFIX ] -then - echo "\$dbPrefix = \"$DB_PREFIX\";" >> /var/www/html/auto-config.inc.php -fi - -if [ ! -z "$DO_NOT_FORCE_PORT" -a "$DO_NOT_FORCE_PORT" == "true" ] -then - echo "\$g_do_not_force_port = true;" >> /var/www/html/auto-config.inc.php -fi - -if [ ! -z "$NEW_UI_ENABLED" -a "$NEW_UI_ENABLED" == "true" ] -then - echo "\$new_ui_enabled = true;" >> /var/www/html/auto-config.inc.php -fi - -if [ ! -z "$AGGREGATOR_MODE_ENABLED" -a "$AGGREGATOR_MODE_ENABLED" == "true" ] -then - echo "\$aggregator_mode_enabled = true;" >> /var/www/html/auto-config.inc.php -fi - -if [ ! -z "$AGGREGATOR_MAX_GEO_WIDTH_KM" ] -then - echo "\$aggregator_max_geo_width_km = ${AGGREGATOR_MAX_GEO_WIDTH_KM};" >> /var/www/html/auto-config.inc.php -fi - -if [ ! -z "$MEETING_STATES_AND_PROVINCES" ] -then - echo "\$meeting_states_and_provinces = \"${MEETING_STATES_AND_PROVINCES}\";" >> /var/www/html/auto-config.inc.php -fi - -if [ ! -z "$MEETING_COUNTIES_AND_SUB_PROVINCES" ] -then - echo "\$meeting_counties_and_sub_provinces = \"${MEETING_COUNTIES_AND_SUB_PROVINCES}\";" >> /var/www/html/auto-config.inc.php -fi - -echo "\$default_duration_time = \"${DEFAULT_DURATION_TIME:-01:00:00}\";" >> /var/www/html/auto-config.inc.php -echo "\$bmlt_title = \"${BMLT_TITLE:-BMLT Administration}\";" >> /var/www/html/auto-config.inc.php -echo "\$bmlt_notice = \"${BMLT_NOTICE:-}\";" >> /var/www/html/auto-config.inc.php - -if [ "$ENABLE_LANGUAGE_SELECTOR" == "false" ]; then - echo "\$g_enable_language_selector = false;" >> /var/www/html/auto-config.inc.php -else - echo "\$g_enable_language_selector = true;" >> /var/www/html/auto-config.inc.php -fi diff --git a/installation/README.md b/installation/README.md index 0e77ce8db..c802e8785 100644 --- a/installation/README.md +++ b/installation/README.md @@ -1,6 +1,6 @@ # Setting Up a BMLT Server -As of version 4.0.0 of the server, we are dropping support for the Installer Wizard. Setting up a completely new server +We dropped support for the Installer Wizard as of version 4.0.0 of the server. Setting up a completely new server is at this point an infrequent event, and hopefully these directions will be clear enough. For a more detailed but older tutorial please see https://bmlt.app/setting-up-the-bmlt/. That tutorial is based on the Installer Wizard, so you'll need to adapt it accordingly. But it may be useful to explain some of the steps. Differences are noted below. @@ -11,21 +11,15 @@ Set up an empty MySQL database, along with a MySQL user that has access to it. ## Uploading the BMLT Server Zip File -Get the latest version of the server from https://github.com/bmlt-enabled/bmlt-server/releases, and upload it to your web hosting provider's server. (The directions for this step in the older tutorial are also still valid.) For this part of the step, upload the zip file *without* unzipping it on your local machine. Then unzip it on your server. You should end up with a directory `main_server` under the directory that holds the files that show up on your website. Thus, if your web hosting server has a directory `public_html` for the files that show up on your website, put `main_server` in that directory, like this: `public_html/main_server`. - -In addition, unzip the file on your laptop or desktop machine -- you'll need to get a couple of files from it in the following steps. But don't try to upload the unzipped file -- that can result in problems with dropped files and such. - -## Initializing the MySQL Database - -This step is different from the old tutorial. - -In the unzipped version of the BMLT Server on your local machine, locate the directory `installation` and find the file `initial-database.sql` in that directory. Import the contents of this file into the empty MySQL database that you set up in the first step. (If you are using cPanel, find the `phpMyAdmin` tool under `Databases`, select your new database, and then click `Import`.) +Get the latest version of the server from https://github.com/bmlt-enabled/bmlt-server/releases using the link labeled `bmlt-server.zip`, and upload it to your web hosting provider's server. (The directions for this step in the older tutorial are also still valid.) For this part of the step, upload `bmlt-server.zip` *without* unzipping it on your local machine. Then unzip it on your server. You should end up with a directory `main_server` under the directory that holds the files that show up on your website. Thus, if your web hosting server has a directory `public_html` for the files that show up on your website, put `main_server` in that directory, like this: `public_html/main_server`. (Again, don't try to upload the unzipped directory from your local machine -- that can result in problems with dropped files and such.) ## Adding the auto-config File This step is also different from the old tutorial. -In the unzipped version of the BMLT Server, look again in the directory `installation` and find the file `initial-auto-config.txt`. Upload this file to your server, put it in the directory that holds your `main_server` directory, and rename it to `auto-config.inc.php`. This file should have the permissions `-rw-r--r--` (`0644` in octal). This means that the owner of the file can read and write it, and the owning group and others can read it. +Download the file `initial-auto-config.txt` from GitHub at https://github.com/bmlt-enabled/bmlt-server/blob/main/installation/initial-auto-config.txt. + +Upload this file to your server, put it in the directory that holds your `main_server` directory, and rename it to `auto-config.inc.php`. This file should have the permissions `-rw-r--r--` (`0644` in octal). This means that the owner of the file can read and write it, and the owning group and others can read it. Note that the file `auto-config.inc.php` is not inside `main_server`, but rather at the same level. This is a little weird, but does have the advantage that you can upload a new version of the server easily without touching the `auto-config.inc.php` file. So your directory structure should look something like this: ``` @@ -37,9 +31,7 @@ public_html ...... ``` -Now edit the `auto-config.inc.php` file with new parameters as needed. You can do this using the `edit` command on cPanel. There are two parameters you definitely need to update, namely `$dbUser` and `$dbPassword` (the user and password for your server database). You also need to either update the parameter `$gkey` if you are using Google Maps, or else delete this parameter altogether if you are using OSM (Open Street Maps) for maps and nominatim for geocoding. - -There are various other parameters in the file, but the default values may well be what you want. +Now edit the `auto-config.inc.php` file with new parameters as needed. You can do this using the `edit` command on cPanel. There are two parameters you definitely need to update, namely `$dbUser` and `$dbPassword` (the user and password for your server database). There are a few other parameters in the file, but the default values may well be what you want. Alternatively, you can edit the `initial-auto-config.txt` file on your local machine, and then upload the edited file, thus avoiding needing to edit it on your web host. If you do that, be sure and use an editor intended for editing source code and not something like Microsoft Word. @@ -50,3 +42,11 @@ Now you should be able to go to the website for your new server (which might be ## Adding Users and Service Bodies At this point you can set up one or more Service Body Administrators and Service Bodies, and start adding meetings. We are now back to steps that are unchanged from the old tutorial, so refer to that for details. + +## Changing Server Settings + +To change server settings, go to the Server Settings item under the Administration tab when logged in as the server admin. One in particular that you may want to change is `Google Maps API Key`. The meeting location map can be displayed using either Google Maps or OpenStreetMap. To use Google maps, set `Google Maps API Key` to your Google api key. To use OpenStreetMap, just skip this step -- the system will default to it if there isn't a Google api key. + +If you export a database to share with others, you should probably set Google Maps API Key to the empty string first. + +For versions of the BMLT server prior to 4.1.0, `auto-config.inc.php` could also contain a large number of additional variable definitions. In 4.1.0, these are moved to the database, and can be inspected or updated using Server Settings. If you are migrating from an older version of the server, there is a migration that runs once when upgrading to 4.1.0 that will copy these values out of `auto-config.inc.php` and into the database. After the migration is run, these other variables in `auto-config.inc.php` will no longer have any effect on the server, and you can simplify `auto-config.inc.php` if you wish. diff --git a/installation/initial-auto-config.txt b/installation/initial-auto-config.txt index a40154a59..ef2b5d146 100644 --- a/installation/initial-auto-config.txt +++ b/installation/initial-auto-config.txt @@ -8,9 +8,6 @@ defined('BMLT_EXEC') or die ('Cannot Execute Directly'); // SETTINGS THAT MUST BE UPDATED $dbUser = 'USERNAME'; // This is the SQL user that is authorized for the above database. $dbPassword = 'USERPASSWORD'; // This is the password for the above authorized user. Make it a big, ugly hairy one. It is powerful, and there is no need to remember it. -$gkey = 'a long string of random characters'; // This is the Google Maps JavaScript API Key, necessary for using Google Maps. -// $gkey is optional -- if you just omit it, the server will use OSM for maps and nominatim for geocoding. -// But if present, it must be a valid Google key. // OTHER DATABASE SETTINGS (CHANGE IF NEEDED, BUT THE DEFAULTS MAY BE OK AS IS) $dbType = 'mysql'; // This is the PHP PDO driver name for your database. @@ -18,39 +15,4 @@ $dbName = 'rootserver'; // This is the name of the database. $dbServer = 'localhost'; // This is the host/server for accessing the database. $dbPrefix = 'na'; // This is a table name prefix that can be used to differentiate tables used by different root server instances that share the same database. -// OTHER SETTINGS FOLLOW (CHANGE IF NEEDED, BUT THE DEFAULTS MAY BE OK AS IS) - -// Location and Map settings: -$region_bias = 'us'; // This is a 2-letter country code for a 'region bias,' which helps figure out ambiguous search queries. -// The default above is for the United States; other examples are 'au' (Australia), 'de' (Germany), 'fr' (France), 'jp' (Japan), etc. -$search_spec_map_center = array('longitude' => -118.563659, 'latitude' => 34.235918, 'zoom' => 6); -// The above coordinates are for the NAWS office in Los Angeles -- change as appropriate -$comdef_distance_units = 'mi'; // the other option is 'km' - -// Display settings: -$bmlt_title = 'Basic Meeting List Toolbox Administration'; -$banner_text = 'Administration Login'; - -// Miscellaneous settings: -$comdef_global_language = 'en'; // This is the 2-letter code for the default root server localization (will default to 'en' -English, if the localization is not available). -$min_pw_len = 10; // The minimum number of characters in a user account password for this root server. -$number_of_meetings_for_auto = 10; // This is an approximation of the number of meetings to search for in the auto-search feature. The higher the number, the wider the radius. -$change_depth_for_meetings = 5; // This is how many changes should be recorded for each meeting. The higher the number, the larger the database will grow, as this can become quite substantial."; -$default_duration_time = '01:30'; // This is the default duration for meetings that have no duration specified. -$g_enable_language_selector = FALSE; // Set this to TRUE (or 1) to enable a popup on the login screen that allows the administrator to select their language. -$g_enable_semantic_admin = TRUE; // If this is TRUE (or 1), then Semantic Administration for this Server is enabled (Administrators can log in using apps). -$g_defaultClosedStatus = TRUE; // If this is FALSE (or 0), then the default (unspecified) Open/Closed format for meetings reported to NAWS is OPEN. Otherwise, it is CLOSED. -// These reflect the way that we handle contact emails. -$g_enable_email_contact = FALSE; // If this is TRUE (or 1), then this will enable the ability to contact meeting list contacts via a secure email form. -$include_service_body_admin_on_emails = FALSE; // If this is TRUE (or 1), then any emails sent using the meeting contact will include the Service Body Admin contact for the meeting Service body (ignored, if $g_enable_email_contact is FALSE). -$include_every_admin_on_emails = FALSE; // If this is TRUE (or 1), then any emails sent using the meeting contact will include all Service Body Admin contacts (including the Server Administrator) for the meeting (ignored, if $g_enable_email_contact or $include_service_body_admin_on_emails is FALSE). - -//The server languages are supported by default, the langs specified here add to them -$format_lang_names = array( -); -// These are 'hard-coded,' but can be changed later: -$time_format = 'g:i A'; // The PHP date() format for the times displayed. -$change_date_format = 'g:i A, n/j/Y'; // The PHP date() format for times/dates displayed in the change records. -$admin_session_name = 'BMLT_Admin'; // This is merely the 'tag' used to identify the BMLT admin session. - ?> diff --git a/installation/initial-database.sql b/installation/initial-database.sql deleted file mode 100644 index 5c61fce9b..000000000 --- a/installation/initial-database.sql +++ /dev/null @@ -1,1080 +0,0 @@ -/*M!999999\- enable the sandbox mode */ --- MariaDB dump 10.19-11.6.2-MariaDB, for debian-linux-gnu (aarch64) --- --- Host: localhost Database: rootserver --- ------------------------------------------------------ --- Server version 11.6.2-MariaDB-ubu2404 - -/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; -/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; -/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; -/*!40101 SET NAMES utf8mb4 */; -/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; -/*!40103 SET TIME_ZONE='+00:00' */; -/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; -/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; -/*M!100616 SET @OLD_NOTE_VERBOSITY=@@NOTE_VERBOSITY, NOTE_VERBOSITY=0 */; - --- --- Table structure for table `na_comdef_changes` --- - -DROP TABLE IF EXISTS `na_comdef_changes`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `na_comdef_changes` ( - `id_bigint` bigint(20) unsigned NOT NULL AUTO_INCREMENT, - `user_id_bigint` bigint(20) unsigned DEFAULT NULL, - `service_body_id_bigint` bigint(20) unsigned NOT NULL, - `lang_enum` varchar(7) NOT NULL, - `change_date` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(), - `object_class_string` varchar(64) NOT NULL, - `change_name_string` varchar(255) DEFAULT NULL, - `change_description_text` text DEFAULT NULL, - `before_id_bigint` bigint(20) unsigned DEFAULT NULL, - `before_lang_enum` varchar(7) DEFAULT NULL, - `after_id_bigint` bigint(20) unsigned DEFAULT NULL, - `after_lang_enum` varchar(7) DEFAULT NULL, - `change_type_enum` varchar(32) NOT NULL, - `before_object` blob DEFAULT NULL, - `after_object` blob DEFAULT NULL, - PRIMARY KEY (`id_bigint`), - KEY `user_id_bigint` (`user_id_bigint`), - KEY `service_body_id_bigint` (`service_body_id_bigint`), - KEY `lang_enum` (`lang_enum`), - KEY `change_type_enum` (`change_type_enum`), - KEY `change_date` (`change_date`), - KEY `before_id_bigint` (`before_id_bigint`), - KEY `after_id_bigint` (`after_id_bigint`), - KEY `before_lang_enum` (`before_lang_enum`), - KEY `after_lang_enum` (`after_lang_enum`), - KEY `object_class_string` (`object_class_string`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `na_comdef_changes` --- - -LOCK TABLES `na_comdef_changes` WRITE; -/*!40000 ALTER TABLE `na_comdef_changes` DISABLE KEYS */; -/*!40000 ALTER TABLE `na_comdef_changes` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `na_comdef_db_version` --- - -DROP TABLE IF EXISTS `na_comdef_db_version`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `na_comdef_db_version` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `version` int(11) NOT NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `na_comdef_db_version` --- - -LOCK TABLES `na_comdef_db_version` WRITE; -/*!40000 ALTER TABLE `na_comdef_db_version` DISABLE KEYS */; -INSERT INTO `na_comdef_db_version` VALUES -(1,21); -/*!40000 ALTER TABLE `na_comdef_db_version` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `na_comdef_format_types` --- - -DROP TABLE IF EXISTS `na_comdef_format_types`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `na_comdef_format_types` ( - `key_string` varchar(10) NOT NULL, - `api_enum` varchar(256) NOT NULL, - `position_int` int(11) NOT NULL, - UNIQUE KEY `na_comdef_format_types_key_string_unique` (`key_string`), - UNIQUE KEY `na_comdef_format_types_api_enum_unique` (`api_enum`), - KEY `na_comdef_format_types_key_string_index` (`key_string`), - KEY `na_comdef_format_types_api_enum_index` (`api_enum`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `na_comdef_format_types` --- - -LOCK TABLES `na_comdef_format_types` WRITE; -/*!40000 ALTER TABLE `na_comdef_format_types` DISABLE KEYS */; -INSERT INTO `na_comdef_format_types` VALUES -('FC1','MEETING_FORMAT',1), -('FC2','LOCATION',2), -('FC3','COMMON_NEEDS_OR_RESTRICTION',3), -('LANG','LANGUAGE',5), -('O','OPEN_OR_CLOSED',4); -/*!40000 ALTER TABLE `na_comdef_format_types` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `na_comdef_formats` --- - -DROP TABLE IF EXISTS `na_comdef_formats`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `na_comdef_formats` ( - `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, - `shared_id_bigint` bigint(20) unsigned NOT NULL, - `root_server_id` bigint(20) unsigned DEFAULT NULL, - `source_id` bigint(20) unsigned DEFAULT NULL, - `key_string` varchar(255) DEFAULT NULL, - `icon_blob` blob DEFAULT NULL, - `worldid_mixed` varchar(255) DEFAULT NULL, - `lang_enum` varchar(7) NOT NULL DEFAULT 'en', - `name_string` varchar(255) DEFAULT NULL, - `description_string` text DEFAULT NULL, - `format_type_enum` varchar(7) DEFAULT 'FC1', - PRIMARY KEY (`id`), - KEY `shared_id_bigint` (`shared_id_bigint`), - KEY `worldid_mixed` (`worldid_mixed`), - KEY `format_type_enum` (`format_type_enum`), - KEY `lang_enum` (`lang_enum`), - KEY `key_string` (`key_string`), - KEY `root_server_id_source_id` (`root_server_id`,`source_id`), - CONSTRAINT `na_comdef_formats_root_server_id_foreign` FOREIGN KEY (`root_server_id`) REFERENCES `na_root_servers` (`id`) ON DELETE CASCADE -) ENGINE=InnoDB AUTO_INCREMENT=500 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `na_comdef_formats` --- - -LOCK TABLES `na_comdef_formats` WRITE; -/*!40000 ALTER TABLE `na_comdef_formats` DISABLE KEYS */; -INSERT INTO `na_comdef_formats` VALUES -(1,1,NULL,NULL,'B',NULL,'BEG','de','Beginners','This meeting is focused on the needs of new members of NA.','FC3'), -(2,2,NULL,NULL,'BL',NULL,'LANG','de','Bi-Lingual','This Meeting can be attended by speakers of English and another language.','LANG'), -(3,3,NULL,NULL,'BT',NULL,'BT','de','Basic Text','This meeting is focused on discussion of the Basic Text of Narcotics Anonymous.','FC1'), -(4,4,NULL,NULL,'C',NULL,'CLOSED','de','Closed','This meeting is closed to non-addicts. You should attend only if you believe that you may have a problem with substance abuse.','O'), -(5,5,NULL,NULL,'CH',NULL,'CH','de','Closed Holidays','This meeting gathers in a facility that is usually closed on holidays.','FC3'), -(6,6,NULL,NULL,'CL',NULL,'CAN','de','Candlelight','This meeting is held by candlelight.','FC2'), -(7,7,NULL,NULL,'CS',NULL,'','de','Children under Supervision','Well-behaved, supervised children are welcome.','FC3'), -(8,8,NULL,NULL,'D',NULL,'DISC','de','Discussion','This meeting invites participation by all attendees.','FC1'), -(9,9,NULL,NULL,'ES',NULL,'LANG','de','Español','This meeting is conducted in Spanish.','LANG'), -(10,10,NULL,NULL,'GL',NULL,'GL','de','Gay/Lesbian/Transgender','This meeting is focused on the needs of gay, lesbian and transgender members of NA.','FC3'), -(11,11,NULL,NULL,'IL',NULL,NULL,'de','Illness','This meeting is focused on the needs of NA members with chronic illness.','FC1'), -(12,12,NULL,NULL,'IP',NULL,'IP','de','Informational Pamphlet','This meeting is focused on discussion of one or more Informational Pamphlets.','FC1'), -(13,13,NULL,NULL,'IW',NULL,'IW','de','It Works -How and Why','This meeting is focused on discussion of the It Works -How and Why text.','FC1'), -(14,14,NULL,NULL,'JT',NULL,'JFT','de','Just for Today','This meeting is focused on discussion of the Just For Today text.','FC1'), -(15,15,NULL,NULL,'M',NULL,'M','de','Men','This meeting is meant to be attended by men only.','FC3'), -(16,16,NULL,NULL,'NC',NULL,'NC','de','No Children','Please do not bring children to this meeting.','FC3'), -(17,17,NULL,NULL,'O',NULL,'OPEN','de','Open','This meeting is open to addicts and non-addicts alike. All are welcome.','O'), -(18,18,NULL,NULL,'Pi',NULL,NULL,'de','Pitch','This meeting has a format that consists of each person who shares picking the next person.','FC1'), -(19,19,NULL,NULL,'RF',NULL,'VAR','de','Rotating Format','This meeting has a format that changes for each meeting.','FC1'), -(20,20,NULL,NULL,'Rr',NULL,NULL,'de','Round Robin','This meeting has a fixed sharing order (usually a circle.)','FC1'), -(21,21,NULL,NULL,'SC',NULL,NULL,'de','Security Cameras','This meeting is held in a facility that has security cameras.','FC2'), -(22,22,NULL,NULL,'SD',NULL,'S-D','de','Speaker/Discussion','This meeting is lead by a speaker, then opened for participation by attendees.','FC1'), -(23,23,NULL,NULL,'SG',NULL,'SWG','de','Step Working Guide','This meeting is focused on discussion of the Step Working Guide text.','FC1'), -(24,24,NULL,NULL,'SL',NULL,NULL,'de','ASL','This meeting provides an American Sign Language (ASL) interpreter for the deaf.','FC2'), -(25,26,NULL,NULL,'So',NULL,'SPK','de','Speaker Only','This meeting is a speaker-only meeting. Other attendees do not participate in the discussion.','FC1'), -(26,27,NULL,NULL,'St',NULL,'STEP','de','Step','This meeting is focused on discussion of the Twelve Steps of NA.','FC1'), -(27,28,NULL,NULL,'Ti',NULL,NULL,'de','Timer','This meeting has sharing time limited by a timer.','FC1'), -(28,29,NULL,NULL,'To',NULL,'TOP','de','Topic','This meeting is based upon a topic chosen by a speaker or by group conscience.','FC1'), -(29,30,NULL,NULL,'Tr',NULL,'TRAD','de','Tradition','This meeting is focused on discussion of the Twelve Traditions of NA.','FC1'), -(30,31,NULL,NULL,'TW',NULL,'TRAD','de','Traditions Workshop','This meeting engages in detailed discussion of one or more of the Twelve Traditions of N.A.','FC1'), -(31,32,NULL,NULL,'W',NULL,'W','de','Women','This meeting is meant to be attended by women only.','FC3'), -(32,33,NULL,NULL,'WC',NULL,'WCHR','de','Wheelchair','This meeting is wheelchair accessible.','FC2'), -(33,34,NULL,NULL,'YP',NULL,'Y','de','Young People','This meeting is focused on the needs of younger members of NA.','FC3'), -(34,35,NULL,NULL,'OE',NULL,NULL,'de','Open-Ended','No fixed duration. The meeting continues until everyone present has had a chance to share.','FC1'), -(35,36,NULL,NULL,'BK',NULL,'LIT','de','Book Study','Approved N.A. Books','FC1'), -(36,37,NULL,NULL,'NS',NULL,'NS','de','No Smoking','Smoking is not allowed at this meeting.','FC1'), -(37,38,NULL,NULL,'Ag',NULL,NULL,'de','Agnostic','Intended for people with varying degrees of Faith.','FC1'), -(38,39,NULL,NULL,'FD',NULL,NULL,'de','Five and Dime','Discussion of the Fifth Step and the Tenth Step','FC1'), -(39,40,NULL,NULL,'AB',NULL,'QA','de','Ask-It-Basket','A topic is chosen from suggestions placed into a basket.','FC1'), -(40,41,NULL,NULL,'ME',NULL,'MED','de','Meditation','This meeting encourages its participants to engage in quiet meditation.','FC1'), -(41,42,NULL,NULL,'RA',NULL,'RA','de','Restricted Attendance','This facility places restrictions on attendees.','FC3'), -(42,43,NULL,NULL,'QA',NULL,'QA','de','Question and Answer','Attendees may ask questions and expect answers from Group members.','FC1'), -(43,44,NULL,NULL,'CW',NULL,'CW','de','Children Welcome','Children are welcome at this meeting.','FC3'), -(44,45,NULL,NULL,'CP',NULL,'CPT','de','Concepts','This meeting is focused on discussion of the twelve concepts of NA.','FC1'), -(45,46,NULL,NULL,'FIN',NULL,'LANG','de','Finnish','Finnish speaking meeting','LANG'), -(46,47,NULL,NULL,'ENG',NULL,'LANG','de','English speaking','This Meeting can be attended by speakers of English.','LANG'), -(47,48,NULL,NULL,'PER',NULL,'LANG','de','Persian','Persian speaking meeting','LANG'), -(48,49,NULL,NULL,'L/R',NULL,'LANG','de','Lithuanian/Russian','Lithuanian/Russian Speaking Meeting','LANG'), -(49,51,NULL,NULL,'LC',NULL,'LC','de','Living Clean','This is a discussion of the NA book Living Clean -The Journey Continues.','FC1'), -(50,52,NULL,NULL,'GP',NULL,'GP','de','Guiding Principles','This is a discussion of the NA book Guiding Principles - The Spirit of Our Traditions.','FC1'), -(51,54,NULL,NULL,'VM',NULL,'VM','de','Virtual Meeting','Meets Virtually','FC2'), -(52,55,NULL,NULL,'TC',NULL,'TC','de','Temporarily Closed Facility','Facility is Temporarily Closed','FC2'), -(53,56,NULL,NULL,'HY',NULL,'HYBR','de','Hybrid Meeting','Meets Virtually and In-person','FC2'), -(54,57,NULL,NULL,'SPAD',NULL,'SPAD','de','Ein spirituelles Prinzip pro Tag','Lesen aus dem Buch Ein spirituelles Prinzip pro Tag','FC1'), -(55,1,NULL,NULL,'B',NULL,'BEG','dk','Beginners','This meeting is focused on the needs of new members of NA.','FC3'), -(56,2,NULL,NULL,'BL',NULL,'LANG','dk','Bi-Lingual','This Meeting can be attended by speakers of English and another language.','LANG'), -(57,3,NULL,NULL,'BT',NULL,'BT','dk','Basic Text','This meeting is focused on discussion of the Basic Text of Narcotics Anonymous.','FC1'), -(58,4,NULL,NULL,'C',NULL,'CLOSED','dk','Closed','This meeting is closed to non-addicts. You should attend only if you believe that you may have a problem with substance abuse.','O'), -(59,5,NULL,NULL,'CH',NULL,'CH','dk','Closed Holidays','This meeting gathers in a facility that is usually closed on holidays.','FC3'), -(60,6,NULL,NULL,'CL',NULL,'CAN','dk','Candlelight','This meeting is held by candlelight.','FC2'), -(61,7,NULL,NULL,'CS',NULL,'','dk','Children under Supervision','Well-behaved, supervised children are welcome.','FC3'), -(62,8,NULL,NULL,'D',NULL,'DISC','dk','Discussion','This meeting invites participation by all attendees.','FC1'), -(63,9,NULL,NULL,'ES',NULL,'LANG','dk','Español','This meeting is conducted in Spanish.','LANG'), -(64,10,NULL,NULL,'GL',NULL,'GL','dk','Gay/Lesbian/Transgender','This meeting is focused on the needs of gay, lesbian and transgender members of NA.','FC3'), -(65,11,NULL,NULL,'IL',NULL,NULL,'dk','Illness','This meeting is focused on the needs of NA members with chronic illness.','FC1'), -(66,12,NULL,NULL,'IP',NULL,'IP','dk','Informational Pamphlet','This meeting is focused on discussion of one or more Informational Pamphlets.','FC1'), -(67,13,NULL,NULL,'IW',NULL,'IW','dk','It Works -How and Why','This meeting is focused on discussion of the It Works -How and Why text.','FC1'), -(68,14,NULL,NULL,'JT',NULL,'JFT','dk','Just for Today','This meeting is focused on discussion of the Just For Today text.','FC1'), -(69,15,NULL,NULL,'M',NULL,'M','dk','Men','This meeting is meant to be attended by men only.','FC3'), -(70,16,NULL,NULL,'NC',NULL,'NC','dk','No Children','Please do not bring children to this meeting.','FC3'), -(71,17,NULL,NULL,'O',NULL,'OPEN','dk','Open','This meeting is open to addicts and non-addicts alike. All are welcome.','O'), -(72,18,NULL,NULL,'Pi',NULL,NULL,'dk','Pitch','This meeting has a format that consists of each person who shares picking the next person.','FC1'), -(73,19,NULL,NULL,'RF',NULL,'VAR','dk','Rotating Format','This meeting has a format that changes for each meeting.','FC1'), -(74,20,NULL,NULL,'Rr',NULL,NULL,'dk','Round Robin','This meeting has a fixed sharing order (usually a circle.)','FC1'), -(75,21,NULL,NULL,'SC',NULL,NULL,'dk','Security Cameras','This meeting is held in a facility that has security cameras.','FC2'), -(76,22,NULL,NULL,'SD',NULL,'S-D','dk','Speaker/Discussion','This meeting is lead by a speaker, then opened for participation by attendees.','FC1'), -(77,23,NULL,NULL,'SG',NULL,'SWG','dk','Step Working Guide','This meeting is focused on discussion of the Step Working Guide text.','FC1'), -(78,24,NULL,NULL,'SL',NULL,NULL,'dk','ASL','This meeting provides an American Sign Language (ASL) interpreter for the deaf.','FC2'), -(79,26,NULL,NULL,'So',NULL,'SPK','dk','Speaker Only','This meeting is a speaker-only meeting. Other attendees do not participate in the discussion.','FC1'), -(80,27,NULL,NULL,'St',NULL,'STEP','dk','Step','This meeting is focused on discussion of the Twelve Steps of NA.','FC1'), -(81,28,NULL,NULL,'Ti',NULL,NULL,'dk','Timer','This meeting has sharing time limited by a timer.','FC1'), -(82,29,NULL,NULL,'To',NULL,'TOP','dk','Topic','This meeting is based upon a topic chosen by a speaker or by group conscience.','FC1'), -(83,30,NULL,NULL,'Tr',NULL,'TRAD','dk','Tradition','This meeting is focused on discussion of the Twelve Traditions of NA.','FC1'), -(84,31,NULL,NULL,'TW',NULL,'TRAD','dk','Traditions Workshop','This meeting engages in detailed discussion of one or more of the Twelve Traditions of N.A.','FC1'), -(85,32,NULL,NULL,'W',NULL,'W','dk','Women','This meeting is meant to be attended by women only.','FC3'), -(86,33,NULL,NULL,'WC',NULL,'WCHR','dk','Wheelchair','This meeting is wheelchair accessible.','FC2'), -(87,34,NULL,NULL,'YP',NULL,'Y','dk','Young People','This meeting is focused on the needs of younger members of NA.','FC3'), -(88,35,NULL,NULL,'OE',NULL,NULL,'dk','Open-Ended','No fixed duration. The meeting continues until everyone present has had a chance to share.','FC1'), -(89,36,NULL,NULL,'BK',NULL,'LIT','dk','Book Study','Approved N.A. Books','FC1'), -(90,37,NULL,NULL,'NS',NULL,'NS','dk','No Smoking','Smoking is not allowed at this meeting.','FC1'), -(91,38,NULL,NULL,'Ag',NULL,NULL,'dk','Agnostic','Intended for people with varying degrees of Faith.','FC1'), -(92,39,NULL,NULL,'FD',NULL,NULL,'dk','Five and Dime','Discussion of the Fifth Step and the Tenth Step','FC1'), -(93,40,NULL,NULL,'AB',NULL,'QA','dk','Ask-It-Basket','A topic is chosen from suggestions placed into a basket.','FC1'), -(94,41,NULL,NULL,'ME',NULL,'MED','dk','Meditation','This meeting encourages its participants to engage in quiet meditation.','FC1'), -(95,42,NULL,NULL,'RA',NULL,'RA','dk','Restricted Attendance','This facility places restrictions on attendees.','FC3'), -(96,43,NULL,NULL,'QA',NULL,'QA','dk','Question and Answer','Attendees may ask questions and expect answers from Group members.','FC1'), -(97,44,NULL,NULL,'CW',NULL,'CW','dk','Children Welcome','Children are welcome at this meeting.','FC3'), -(98,45,NULL,NULL,'CP',NULL,'CPT','dk','Concepts','This meeting is focused on discussion of the twelve concepts of NA.','FC1'), -(99,46,NULL,NULL,'FIN',NULL,'LANG','dk','Finnish','Finnish speaking meeting','LANG'), -(100,47,NULL,NULL,'ENG',NULL,'LANG','dk','English speaking','This Meeting can be attended by speakers of English.','LANG'), -(101,48,NULL,NULL,'PER',NULL,'LANG','dk','Persian','Persian speaking meeting','LANG'), -(102,49,NULL,NULL,'L/R',NULL,'LANG','dk','Lithuanian/Russian','Lithuanian/Russian Speaking Meeting','LANG'), -(103,51,NULL,NULL,'LC',NULL,'LC','dk','Living Clean','This is a discussion of the NA book Living Clean -The Journey Continues.','FC1'), -(104,52,NULL,NULL,'GP',NULL,'GP','dk','Guiding Principles','This is a discussion of the NA book Guiding Principles - The Spirit of Our Traditions.','FC1'), -(105,54,NULL,NULL,'VM',NULL,'VM','dk','Virtual Meeting','Meets Virtually','FC2'), -(106,55,NULL,NULL,'TC',NULL,'TC','dk','Temporarily Closed Facility','Facility is Temporarily Closed','FC2'), -(107,56,NULL,NULL,'HY',NULL,'HYBR','dk','Hybrid Meeting','Meets Virtually and In-person','FC2'), -(108,1,NULL,NULL,'B',NULL,'BEG','en','Beginners','This meeting is focused on the needs of new members of NA.','FC3'), -(109,2,NULL,NULL,'BL',NULL,'LANG','en','Bi-Lingual','This Meeting can be attended by speakers of English and another language.','LANG'), -(110,3,NULL,NULL,'BT',NULL,'BT','en','Basic Text','This meeting is focused on discussion of the Basic Text of Narcotics Anonymous.','FC1'), -(111,4,NULL,NULL,'C',NULL,'CLOSED','en','Closed','This meeting is closed to non-addicts. You should attend only if you believe that you may have a problem with substance abuse.','O'), -(112,5,NULL,NULL,'CH',NULL,'CH','en','Closed Holidays','This meeting gathers in a facility that is usually closed on holidays.','FC3'), -(113,6,NULL,NULL,'CL',NULL,'CAN','en','Candlelight','This meeting is held by candlelight.','FC2'), -(114,7,NULL,NULL,'CS',NULL,'','en','Children under Supervision','Well-behaved, supervised children are welcome.','FC3'), -(115,8,NULL,NULL,'D',NULL,'DISC','en','Discussion','This meeting invites participation by all attendees.','FC1'), -(116,9,NULL,NULL,'ES',NULL,'LANG','en','Español','This meeting is conducted in Spanish.','LANG'), -(117,10,NULL,NULL,'GL',NULL,'GL','en','Gay/Lesbian/Transgender','This meeting is focused on the needs of gay, lesbian and transgender members of NA.','FC3'), -(118,11,NULL,NULL,'IL',NULL,NULL,'en','Illness','This meeting is focused on the needs of NA members with chronic illness.','FC1'), -(119,12,NULL,NULL,'IP',NULL,'IP','en','Informational Pamphlet','This meeting is focused on discussion of one or more Informational Pamphlets.','FC1'), -(120,13,NULL,NULL,'IW',NULL,'IW','en','It Works -How and Why','This meeting is focused on discussion of the It Works -How and Why text.','FC1'), -(121,14,NULL,NULL,'JT',NULL,'JFT','en','Just for Today','This meeting is focused on discussion of the Just For Today text.','FC1'), -(122,15,NULL,NULL,'M',NULL,'M','en','Men','This meeting is meant to be attended by men only.','FC3'), -(123,16,NULL,NULL,'NC',NULL,'NC','en','No Children','Please do not bring children to this meeting.','FC3'), -(124,17,NULL,NULL,'O',NULL,'OPEN','en','Open','This meeting is open to addicts and non-addicts alike. All are welcome.','O'), -(125,18,NULL,NULL,'Pi',NULL,NULL,'en','Pitch','This meeting has a format that consists of each person who shares picking the next person.','FC1'), -(126,19,NULL,NULL,'RF',NULL,'VAR','en','Rotating Format','This meeting has a format that changes for each meeting.','FC1'), -(127,20,NULL,NULL,'Rr',NULL,NULL,'en','Round Robin','This meeting has a fixed sharing order (usually a circle.)','FC1'), -(128,21,NULL,NULL,'SC',NULL,NULL,'en','Security Cameras','This meeting is held in a facility that has security cameras.','FC2'), -(129,22,NULL,NULL,'SD',NULL,'S-D','en','Speaker/Discussion','This meeting is lead by a speaker, then opened for participation by attendees.','FC1'), -(130,23,NULL,NULL,'SG',NULL,'SWG','en','Step Working Guide','This meeting is focused on discussion of the Step Working Guide text.','FC1'), -(131,24,NULL,NULL,'SL',NULL,NULL,'en','ASL','This meeting provides an American Sign Language (ASL) interpreter for the deaf.','FC2'), -(132,26,NULL,NULL,'So',NULL,'SPK','en','Speaker Only','This meeting is a speaker-only meeting. Other attendees do not participate in the discussion.','FC1'), -(133,27,NULL,NULL,'St',NULL,'STEP','en','Step','This meeting is focused on discussion of the Twelve Steps of NA.','FC1'), -(134,28,NULL,NULL,'Ti',NULL,NULL,'en','Timer','This meeting has sharing time limited by a timer.','FC1'), -(135,29,NULL,NULL,'To',NULL,'TOP','en','Topic','This meeting is based upon a topic chosen by a speaker or by group conscience.','FC1'), -(136,30,NULL,NULL,'Tr',NULL,'TRAD','en','Tradition','This meeting is focused on discussion of the Twelve Traditions of NA.','FC1'), -(137,31,NULL,NULL,'TW',NULL,'TRAD','en','Traditions Workshop','This meeting engages in detailed discussion of one or more of the Twelve Traditions of N.A.','FC1'), -(138,32,NULL,NULL,'W',NULL,'W','en','Women','This meeting is meant to be attended by women only.','FC3'), -(139,33,NULL,NULL,'WC',NULL,'WCHR','en','Wheelchair','This meeting is wheelchair accessible.','FC2'), -(140,34,NULL,NULL,'YP',NULL,'Y','en','Young People','This meeting is focused on the needs of younger members of NA.','FC3'), -(141,35,NULL,NULL,'OE',NULL,NULL,'en','Open-Ended','No fixed duration. The meeting continues until everyone present has had a chance to share.','FC1'), -(142,36,NULL,NULL,'BK',NULL,'LIT','en','Book Study','Approved N.A. Books','FC1'), -(143,37,NULL,NULL,'NS',NULL,'NS','en','No Smoking','Smoking is not allowed at this meeting.','FC1'), -(144,38,NULL,NULL,'Ag',NULL,NULL,'en','Agnostic','Intended for people with varying degrees of Faith.','FC1'), -(145,39,NULL,NULL,'FD',NULL,NULL,'en','Five and Dime','Discussion of the Fifth Step and the Tenth Step','FC1'), -(146,40,NULL,NULL,'AB',NULL,'QA','en','Ask-It-Basket','A topic is chosen from suggestions placed into a basket.','FC1'), -(147,41,NULL,NULL,'ME',NULL,'MED','en','Meditation','This meeting encourages its participants to engage in quiet meditation.','FC1'), -(148,42,NULL,NULL,'RA',NULL,'RA','en','Restricted Attendance','This facility places restrictions on attendees.','FC3'), -(149,43,NULL,NULL,'QA',NULL,'QA','en','Question and Answer','Attendees may ask questions and expect answers from Group members.','FC1'), -(150,44,NULL,NULL,'CW',NULL,'CW','en','Children Welcome','Children are welcome at this meeting.','FC3'), -(151,45,NULL,NULL,'CP',NULL,'CPT','en','Concepts','This meeting is focused on discussion of the twelve concepts of NA.','FC1'), -(152,46,NULL,NULL,'FIN',NULL,'LANG','en','Finnish','Finnish speaking meeting','LANG'), -(153,47,NULL,NULL,'ENG',NULL,'LANG','en','English speaking','This Meeting can be attended by speakers of English.','LANG'), -(154,48,NULL,NULL,'PER',NULL,'LANG','en','Persian','Persian speaking meeting','LANG'), -(155,49,NULL,NULL,'L/R',NULL,'LANG','en','Lithuanian/Russian','Lithuanian/Russian Speaking Meeting','LANG'), -(156,51,NULL,NULL,'LC',NULL,'LC','en','Living Clean','This is a discussion of the NA book Living Clean -The Journey Continues.','FC1'), -(157,52,NULL,NULL,'GP',NULL,'GP','en','Guiding Principles','This is a discussion of the NA book Guiding Principles - The Spirit of Our Traditions.','FC1'), -(158,54,NULL,NULL,'VM',NULL,'VM','en','Virtual Meeting','Meets Virtually','FC2'), -(159,55,NULL,NULL,'TC',NULL,'TC','en','Temporarily Closed Facility','Facility is Temporarily Closed','FC2'), -(160,56,NULL,NULL,'HY',NULL,'HYBR','en','Hybrid Meeting','Meets Virtually and In-person','FC2'), -(161,57,NULL,NULL,'SPAD',NULL,'SPAD','en','A Spiritual Principle a Day','This meeting is focused on discussion of the book A Spiritual Principle a Day.','FC1'), -(162,1,NULL,NULL,'B',NULL,'BEG','es','Para el recién llegado','Esta reunión se centra en las necesidades de los nuevos miembros de NA.','FC3'), -(163,2,NULL,NULL,'BL',NULL,'LANG','es','Bilingüe','Esta reunión se pueden asistir personas de que hablen inglés y otro idioma.','LANG'), -(164,3,NULL,NULL,'BT',NULL,'BT','es','Texto Básico','Esta reunión se centra en la discusión del texto básico de Narcóticos Anónimos.','FC1'), -(165,4,NULL,NULL,'C',NULL,'CLOSED','es','Cerrado','Esta reunión está cerrada a los no adictos. Usted debe asistir solamente si cree que puede tener un problema con abuso de drogas.','O'), -(166,5,NULL,NULL,'CH',NULL,NULL,'es','Cerrado en Días de fiesta','Esta reunión tiene lugar en una localidad que esta generalmente cerrada los días de fiesta.','FC3'), -(167,6,NULL,NULL,'CL',NULL,'CAN','es','Luz de vela','Esta reunión se celebra a luz de vela.','FC2'), -(168,7,NULL,NULL,'CS',NULL,'','es','Niños bajo Supervisión','Los niños de buen comportamiento y supervisados son bienvenidos.','FC3'), -(169,8,NULL,NULL,'D',NULL,'DISC','es','Discusión','Esta reunión invita la participación de todos los asistentes.','FC1'), -(170,10,NULL,NULL,'GL',NULL,'GL','es','Gay/Lesbiana','Esta reunión se centra en las necesidades de miembros gay y lesbianas de NA.','FC3'), -(171,11,NULL,NULL,'IL',NULL,NULL,'es','Enfermedad','Esta reunión se centra en las necesidades de los miembros de NA con enfermedades crónicas.','FC1'), -(172,12,NULL,NULL,'IP',NULL,'IP','es','Folleto Informativo','Esta reunión se centra en la discusión de unos o más folletos informativos.','FC1'), -(173,13,NULL,NULL,'IW',NULL,'IW','es','Functiona - Cómo y Porqué','Esta reunión se centra en la discusión del texto Funciona - Cómo y Porqué.','FC1'), -(174,14,NULL,NULL,'JT',NULL,'JFT','es','Solo por Hoy','Esta reunión se centra en la discusión del texto Solo por Hoy.','FC1'), -(175,15,NULL,NULL,'M',NULL,'M','es','Hombres','A esta reunión se supone que aistan hombres solamente.','FC3'), -(176,16,NULL,NULL,'NC',NULL,NULL,'es','No niños','Por favor no traer niños a esta reunión.','FC3'), -(177,17,NULL,NULL,'O',NULL,'OPEN','es','Abierta','Esta reunión está abierta a los adictos y a los no adictos por igual. Todos son bienvenidos.','O'), -(178,18,NULL,NULL,'Pi',NULL,NULL,'es','Echada','Esta reunión tiene un formato que consiste en que cada persona que comparta escoja a la persona siguiente.','FC1'), -(179,19,NULL,NULL,'RF',NULL,'VAR','es','Formato que Rota','Esta reunión tiene un formato que cambia para cada reunión.','FC1'), -(180,20,NULL,NULL,'Rr',NULL,NULL,'es','Round Robin','Esta reunión tiene un orden fijo de compartir (generalmente un círculo).','FC1'), -(181,21,NULL,NULL,'SC',NULL,NULL,'es','Cámaras de Vigilancia','Esta reunión se celebra en una localidad que tenga cámaras de vigilancia.','FC2'), -(182,22,NULL,NULL,'SD',NULL,'S-D','es','Orador/Discusión','Esta reunión es conducida por un orador, después es abierta para la participación de los asistentes.','FC1'), -(183,23,NULL,NULL,'SG',NULL,'SWG','es','Guia Para Trabajar los Pasos','Esta reunión se centra en la discusión del texto Guia Para Trabajar los Pasos.','FC1'), -(184,24,NULL,NULL,'SL',NULL,NULL,'es','ASL','Esta reunión proporciona intérprete (ASL) para los sordos.','FC2'), -(185,26,NULL,NULL,'So',NULL,'SPK','es','Solamente Orador','Esta reunión es de orador solamente. Otros asistentes no participan en la discusión.','FC1'), -(186,27,NULL,NULL,'St',NULL,'STEP','es','Paso','Esta reunión se centra en la discusión de los doce pasos de NA.','FC1'), -(187,28,NULL,NULL,'Ti',NULL,NULL,'es','Contador de Tiempo','Esta reunión tiene el tiempo de compartir limitado por un contador de tiempo.','FC1'), -(188,29,NULL,NULL,'To',NULL,'TOP','es','Tema','Esta reunión se basa en un tema elegido por el orador o por la conciencia del grupo.','FC1'), -(189,30,NULL,NULL,'Tr',NULL,'TRAD','es','Tradición','Esta reunión se centra en la discusión de las Doce Tradiciones de NA.','FC1'), -(190,31,NULL,NULL,'TW',NULL,'TRAD','es','Taller de las Tradiciones','Esta reunión consiste en la discusión detallada de una o más de las Doce Tradiciones de N.A.','FC1'), -(191,32,NULL,NULL,'W',NULL,'W','es','Mujeres','A esta reunión se supone que asistan mujeres solamente.','FC3'), -(192,33,NULL,NULL,'WC',NULL,'WCHR','es','Silla de Ruedas','Esta reunión es accesible por silla de ruedas.','FC2'), -(193,34,NULL,NULL,'YP',NULL,'Y','es','Jovenes','Esta reunión se centra en las necesidades de los miembros más jóvenes de NA.','FC3'), -(194,35,NULL,NULL,'OE',NULL,NULL,'es','Sin Tiempo Fijo','No tiene tiempo fijo. Esta reunión continua hasta que cada miembro haya tenido la oportunidad de compartir.','FC1'), -(195,54,NULL,NULL,'VM',NULL,'VM','es','Virtual Meeting','Meets Virtually','FC2'), -(196,55,NULL,NULL,'TC',NULL,'TC','es','Temporarily Closed Facility','Facility is Temporarily Closed','FC2'), -(197,56,NULL,NULL,'HY',NULL,'HYBR','es','Hybrid Meeting','Meets Virtually and In-person','FC2'), -(198,54,NULL,NULL,'VM',NULL,'VM','fa','Virtual Meeting','Meets Virtually','FC2'), -(199,55,NULL,NULL,'TC',NULL,'TC','fa','Temporarily Closed Facility','Facility is Temporarily Closed','FC2'), -(200,56,NULL,NULL,'HY',NULL,'HYBR','fa','Hybrid Meeting','Meets Virtually and In-person','FC2'), -(201,1,NULL,NULL,'B',NULL,'BEG','fr','Débutants','Cette réunion est axée sur les besoins des nouveaux membres de NA.','FC3'), -(202,2,NULL,NULL,'BL',NULL,'LANG','fr','bilingue','Cette réunion peut aider les personnes qui parlent l\'anglais et une autre langue.','LANG'), -(203,3,NULL,NULL,'BT',NULL,'BT','fr','Texte de Base','Cette réunion est axée sur la discussion du texte de base de Narcotiques Anonymes.','FC1'), -(204,4,NULL,NULL,'C',NULL,'CLOSED','fr','Fermée','Cette réunion est fermée aux non-toxicomanes. Vous pouvez y assister que si vous pensez que vous pouvez avoir un problème avec l\'abus de drogues.','O'), -(205,5,NULL,NULL,'CH',NULL,NULL,'fr','Fermé durant les jours fériés.','Cette réunion a lieu dans une local qui est généralement fermé durant les jours fériés.','FC3'), -(206,6,NULL,NULL,'CL',NULL,'CAN','fr','Chandelle','Cette réunion se déroule à la chandelle.','FC2'), -(207,7,NULL,NULL,'CS',NULL,'','fr','Enfants sous Supervision','Les enfants bien élevés sont les bienvenus et supervisés.','FC3'), -(208,8,NULL,NULL,'D',NULL,'DISC','fr','Discussion','Cette réunion invite tous les participants à la discussion.','FC1'), -(209,10,NULL,NULL,'GL',NULL,'GL','fr','Gais, lesbiennes, transsexuel(le)s, bisexuel(le)s','Cette réunion est axée sur les besoins des membres gais, lesbiennes, transsexuel(le)s et bisexuel(le)s de NA.','FC3'), -(210,11,NULL,NULL,'IL',NULL,NULL,'fr','Chroniques','Cette réunion est axée sur les besoins des membres de NA comportant des troubles de maladies chroniques.','FC1'), -(211,12,NULL,NULL,'IP',NULL,'IP','fr','Brochures','Cette réunion est axée sur la discussion d\'une ou plusieurs brochures.','FC1'), -(212,13,NULL,NULL,'IW',NULL,'IW','fr','Ça marche, Comment et Pourquoi','Cette session met l\'accent sur la discussion de texte Ça marche, Comment et Pourquoi.','FC1'), -(213,14,NULL,NULL,'JT',NULL,'JFT','fr','Juste pour aujourd\'hui','Cette session met l\'accent sur la discussion du texte Juste pour aujourd\'hui.','FC1'), -(214,15,NULL,NULL,'M',NULL,'M','fr','Hommes','Cette réunion est destinée à être assisté par seulement que des hommes.','FC3'), -(215,16,NULL,NULL,'NC',NULL,NULL,'fr','Pas d\'enfant','S\'il vous plaît, ne pas amener les enfants à cette réunion.','FC3'), -(216,17,NULL,NULL,'O',NULL,'OPEN','fr','Ouvert','Cette réunion est ouverte aux toxicomanes et non-toxicomanes de même. Tous sont les bienvenus.','O'), -(217,18,NULL,NULL,'Pi',NULL,NULL,'fr','À la pige','Cette réunion a un format de discussion est que chaque personne qui discute invite la personne suivante à discuter.','FC1'), -(218,19,NULL,NULL,'RF',NULL,'VAR','fr','Format varié','Cette réunion a un format qui varie à toutes les réunions.','FC1'), -(219,20,NULL,NULL,'Rr',NULL,NULL,'fr','À la ronde','Cette réunion a un ordre de partage fixe (généralement un cercle).','FC1'), -(220,21,NULL,NULL,'SC',NULL,NULL,'fr','Caméra de surveillance','Cette réunion se tient dans un emplacement qui a des caméras de surveillance.','FC2'), -(221,22,NULL,NULL,'SD',NULL,'S-D','fr','Partage et ouvert','Cette réunion a un conférencier, puis ouvert au public.','FC1'), -(222,23,NULL,NULL,'SG',NULL,'SWG','fr','Guides des Étapes','Cette réunion est axée sur la discussion sur le Guide des Étapes.','FC1'), -(223,24,NULL,NULL,'SL',NULL,NULL,'fr','Malentendants','Cette rencontre permet l\'interprète pour les personnes malentendantes.','FC2'), -(224,26,NULL,NULL,'So',NULL,'SPK','fr','Partage seulement','Cette réunion a seulement un conférencier. Les autres participants ne participent pas à la discussion.','FC1'), -(225,27,NULL,NULL,'St',NULL,'STEP','fr','Étapes NA','Cette réunion est axée sur la discussion des Douze Étapes de NA.','FC1'), -(226,28,NULL,NULL,'Ti',NULL,NULL,'fr','Discussion chronométrée','Cette réunion a une durée de discussion limitée par une minuterie pour chaque personne.','FC1'), -(227,29,NULL,NULL,'To',NULL,'TOP','fr','Thématique','Cette réunion est basée sur un thème choisi par la personne qui anime ou la conscience de groupe.','FC1'), -(228,30,NULL,NULL,'Tr',NULL,'TRAD','fr','Traditions','Cette réunion est axée sur la discussion des Douze Traditions de NA.','FC1'), -(229,31,NULL,NULL,'TW',NULL,'TRAD','fr','Atelier sur les traditions','Cette réunion est une discussion détaillée d\'une ou de plusieurs des Douze Traditions de NA','FC1'), -(230,32,NULL,NULL,'W',NULL,'W','fr','Femmes','Seulement les femmes sont admises.','FC3'), -(231,33,NULL,NULL,'WC',NULL,'WCHR','fr','Fauteuil Roulant','Cette réunion est accessible en fauteuil roulant.','FC2'), -(232,34,NULL,NULL,'YP',NULL,'Y','fr','Jeunes','Cette réunion est axée sur les besoins des plus jeunes membres de NA.','FC3'), -(233,35,NULL,NULL,'OE',NULL,NULL,'fr','Marathon','Il n\'y a pas de durée fixe. Cette réunion se poursuit jusqu\'à ce que chaque membre a eu l\'occasion de partager.','FC1'), -(234,36,NULL,NULL,'BK',NULL,'LIT','fr','Études de livres NA','Livres N.A. Approuvés','FC1'), -(235,37,NULL,NULL,'NS',NULL,'NS','fr','Non-fumeurs','Fumer n\'est pas permis à cette réunion.','FC1'), -(236,38,NULL,NULL,'Ag',NULL,NULL,'fr','Agnostique','Destiné aux personnes ayant divers degrés de la foi.','FC1'), -(237,39,NULL,NULL,'FD',NULL,NULL,'fr','Cinq et dix','Discussion de la cinquième étape et la dixième étape.','FC1'), -(238,40,NULL,NULL,'AB',NULL,'QA','fr','Panier','Un sujet est choisi parmi les suggestions placées dans un panier.','FC1'), -(239,41,NULL,NULL,'ME',NULL,'MED','fr','Méditation','Cette réunion encourage ses participants à s\'engager dans la méditation tranquille.','FC1'), -(240,42,NULL,NULL,'RA',NULL,'RA','fr','Accés limités','Cet emplacement impose des restrictions sur les participants.','FC3'), -(241,43,NULL,NULL,'QA',NULL,'QA','fr','Questions et Réponses','Les participants peuvent poser des questions et attendre des réponses des membres du groupe.','FC1'), -(242,44,NULL,NULL,'CW',NULL,'CW','fr','Enfants bienvenus','Les enfants sont les bienvenus à cette réunion.','FC3'), -(243,45,NULL,NULL,'CP',NULL,'CPT','fr','Concepts','Cette réunion est axée sur la discussion des douze concepts de NA.','FC1'), -(244,46,NULL,NULL,'Finlandais',NULL,NULL,'fr','Finlandais','Cette réunion se déroule en langue finlandaisè','FC3'), -(245,47,NULL,NULL,'ENG',NULL,NULL,'fr','Anglais','Cette réunion se déroule de langues anglais.','FC3'), -(246,54,NULL,NULL,'VM',NULL,'VM','fr','Virtual Meeting','Meets Virtually','FC2'), -(247,55,NULL,NULL,'TC',NULL,'TC','fr','Temporarily Closed Facility','Facility is Temporarily Closed','FC2'), -(248,56,NULL,NULL,'HY',NULL,'HYBR','fr','Hybrid Meeting','Meets Virtually and In-person','FC2'), -(249,1,NULL,NULL,'NV',NULL,NULL,'it','Nuovi venuti','Riunione concentrata principalmente sulle necessità dei nuovi membri di NA.','FC3'), -(250,2,NULL,NULL,'BL',NULL,'LANG','it','Bilingue','Questa riunione può essere frequentata da membri che parlano italiano e/o inglese.','LANG'), -(251,3,NULL,NULL,'TB',NULL,NULL,'it','Testo base','Riunione concentrata sulla discussione del testo base di NA.','FC1'), -(252,4,NULL,NULL,'Ch.',NULL,NULL,'it','Chiusa','Riunione chiusa ai non dipendenti. Dovrebbe frequentarla soltanto chi crede di avere un problema con le sostanze d\'abuso.','O'), -(253,5,NULL,NULL,'SF',NULL,NULL,'it','Sospesa nei giorni festivi','Questa riunione si tiene in locali che di solito sono chiusi nei giorni festivi e di vacanza.','FC3'), -(254,6,NULL,NULL,'LC',NULL,NULL,'it','Lume di candela','Questa riunione si tiene a lume di candela per favorire la meditazione.','FC2'), -(255,7,NULL,NULL,'BS',NULL,NULL,'it','Bambini sotto supervisione','Sono ammessi bambini senza problemi di comportamento e sotto supervisione.','FC3'), -(256,8,NULL,NULL,'Disc.',NULL,NULL,'it','Discussione','Tutti i partecipanti sono invitati a condividere.','FC1'), -(257,9,NULL,NULL,'ES',NULL,'LANG','it','Spagnolo','Riunione in lingua spagnolo.','FC3'), -(258,14,NULL,NULL,'SPO',NULL,NULL,'it','Solo per oggi','Riunione in cui si discutono i temi delle meditazioni quotidiane del libro \"Solo per oggi\".','FC1'), -(259,15,NULL,NULL,'U',NULL,NULL,'it','Uomini','Riunioni per soli uomini.','FC3'), -(260,17,NULL,NULL,'Ap.',NULL,NULL,'it','Aperta','Riunione aperta ai non dipendenti. Parenti, amici, professionisti e altri membri della società, sono benvenuti.','O'), -(261,23,NULL,NULL,'GLP',NULL,NULL,'it','Guida al lavoro sui passi','Riunione basata sulla discussione della Guida al lavoro sui Dodici passi di NA.','FC1'), -(262,28,NULL,NULL,'Temp.',NULL,NULL,'it','Condivisioni temporizzate','In queste riunioni il tempo di condivisione è limitato da un cronometro.','FC1'), -(263,27,NULL,NULL,'P',NULL,NULL,'it','Passi','Riunione di discussione sui Dodici passi.','FC1'), -(264,29,NULL,NULL,'Arg.',NULL,NULL,'it','Riunioni a tema','Queste riunioni si basano su un argomento prescelto.','FC1'), -(265,30,NULL,NULL,'T',NULL,NULL,'it','Tradizioni','Riunione di discussione sulle Dodici tradizioni.','FC1'), -(266,31,NULL,NULL,'TW',NULL,NULL,'it','Workshop sulle Dodici tradizioni','Riunioni in cui si discute dettagliatamente su una o più delle Dodici tradizioni.','FC1'), -(267,32,NULL,NULL,'D',NULL,NULL,'it','Donne','Riunione solo donne.','FC3'), -(268,33,NULL,NULL,'SR',NULL,NULL,'it','Sedia a rotelle','Riunione accessibile per chi ha la sedia a rotelle.','FC2'), -(269,35,NULL,NULL,'M',NULL,NULL,'it','Maratona','Durata non prestabilita. La riunione prosegue finché tutti i presenti hanno da condividere.','FC1'), -(270,37,NULL,NULL,'NF',NULL,NULL,'it','Non fumatori','In queste riunioni non è consentito fumare.','FC1'), -(271,40,NULL,NULL,'TS',NULL,NULL,'it','Tema a sorpresa','L\'argomento su cui condividere è scritto su un biglietto o altro supporto (es. un bastoncino di legno) ed estratto a caso da ciascun membro.','FC1'), -(272,42,NULL,NULL,'M',NULL,NULL,'it','Meditazione','In questa riunione sono poste restrizioni alle modalità di partecipazione.','FC3'), -(273,43,NULL,NULL,'D/R',NULL,NULL,'it','Domande e risposteq','I partecipanti possono fare domande e attenderne la risposta dagli altri membri del gruppo.','FC1'), -(274,44,NULL,NULL,'Ba',NULL,NULL,'it','Bambini','I bambini sono benvenuti in queste riunioni.','FC3'), -(275,45,NULL,NULL,'C',NULL,NULL,'it','Concetti di servizio','Riunioni basate sulla discussione dei Dodici concetti per il servizio in NA.','FC1'), -(276,51,NULL,NULL,'VP',NULL,NULL,'it','Vivere puliti','Riunioni di discussione sul libro \"Vivere puliti - Il viaggio continua\".','FC1'), -(277,54,NULL,NULL,'VM',NULL,'VM','it','Virtual Meeting','Meets Virtually','FC2'), -(278,55,NULL,NULL,'TC',NULL,'TC','it','Temporarily Closed Facility','Facility is Temporarily Closed','FC2'), -(279,56,NULL,NULL,'HY',NULL,'HYBR','it','Hybrid Meeting','Meets Virtually and In-person','FC2'), -(280,1,NULL,NULL,'B',NULL,'BEG','pl','Nowoprzybyli','Mityng koncentruje się na potrzebach nowyh członków NA.','FC3'), -(281,2,NULL,NULL,'BL',NULL,'LANG','pl','Wielojęzykowość','Na tym mityngu mogą uczęszczać osoby posługujące się językiem angielskim i innymi.','LANG'), -(282,3,NULL,NULL,'BT',NULL,'BT','pl','Tekst Podstawowy','Mityng koncentruje się na dyskusjach o Tekście Podstawowym Anonimowych Narkomanów.','FC1'), -(283,4,NULL,NULL,'C',NULL,'CLOSED','pl','Mityng zamknięty','Mityng zamknięty. Wyłącznie dla osób uzależnionych i tych, które chcą przestać brać.','O'), -(284,5,NULL,NULL,'CH',NULL,'CH','pl','Zamknięty w święta','Mityng odbywa się w miejscu, które zwykle jest zamknięte w dni wolne od pracy/wakacje.','FC3'), -(285,6,NULL,NULL,'CL',NULL,'CAN','pl','Świeczka','Ten mityng odbywa się przy blasku świecy.','FC2'), -(286,7,NULL,NULL,'CS',NULL,'','pl','Dzieci pod opieką','Dzieci uzależnionych mile widziane pod warunkiem odpowiedniego zachowania.','FC3'), -(287,8,NULL,NULL,'D',NULL,'DISC','pl','Dyskusja','Mityng dla wszystkich chętnych.','FC1'), -(288,9,NULL,NULL,'ES',NULL,'LANG','pl','Hiszpański','Mityng odbywa się w języku hiszpańskim.','LANG'), -(289,10,NULL,NULL,'GL',NULL,'GL','pl','LGBTQ','Mityng koncentruje się na członkach wspólnoty należących do społeczności LGBT.','FC3'), -(290,11,NULL,NULL,'IL',NULL,NULL,'pl','Choroba','Mityng koncentruje się na potrzebach przewlekle chorych członków NA.','FC1'), -(291,12,NULL,NULL,'IP',NULL,'IP','pl','Broszura Informacyjna','Mityng koncentruje się na dyskusji nad jedną z Broszur Międzynarodowych.','FC1'), -(292,13,NULL,NULL,'IW',NULL,'IW','pl','To Działa - Jak i Dlaczego','Mityng koncentruje się na dyskusji nad tekstem z \"To Działa - Jak i Dlaczego\".','FC1'), -(293,14,NULL,NULL,'JT',NULL,'JFT','pl','Właśnie Dzisiaj','Mityng koncentruje się na dyskusji nad tekstem z \"Właśnie dzisiaj\".','FC1'), -(294,15,NULL,NULL,'M',NULL,'M','pl','Mężczyźni','Mityng wyłącznie dla mężczyzn.','FC3'), -(295,16,NULL,NULL,'NC',NULL,'NC','pl','Bez Dzieci','Prosimy, by nie przyprowadzać dzieci na ten mityng.','FC3'), -(296,17,NULL,NULL,'O',NULL,'OPEN','pl','Otwarty','Mityng otwarty dla uzależnionych i nieuzależnionych. Wszyscy są mile widziani.','O'), -(297,18,NULL,NULL,'Pi',NULL,NULL,'pl','Pitch','Na tym mityngu obowiązuje format, w którym osoba, dzieląca się doświadczeniem, wybiera kolejną osobę.','FC1'), -(298,19,NULL,NULL,'RF',NULL,'VAR','pl','Zmienny format','Format tego mityngu zmienia się co mityng.','FC1'), -(299,20,NULL,NULL,'Rr',NULL,NULL,'pl','Round Robin','Na tym mityngu jest ustalona kolejność dzielenia się doświadczeniem (zwykle w koło)','FC1'), -(300,21,NULL,NULL,'SC',NULL,NULL,'pl','Kamery bezpieczeństwa','Mityng odbywa się w miejscu, w którym zamontowane są kamery bezpieczeństwa.','FC2'), -(301,22,NULL,NULL,'SD',NULL,'S-D','pl','Spikerka/dyskusja','Mityng rozpoczynany jest wypowiedzią spikera, a następnie jest otwarty do dzielenia się przez resztę uczestników.','FC1'), -(302,23,NULL,NULL,'SG',NULL,'SWG','pl','Przewodnik pracy nad Krokami','Mityng koncentruje się na dyskusji nad tekstem z \"Przewodnika do pracy nad Krokami\".','FC1'), -(303,24,NULL,NULL,'SL',NULL,NULL,'pl','ASL','W tym mityngu bierze udział tłumacz języka migowego dla osób niesłyszących.','FC2'), -(304,26,NULL,NULL,'So',NULL,'SPK','pl','Tylko spikerka','Mityng składa się tylko z wypowiedzi spikera. Inni uczestnicy nie dzielą się doświadczeniem.','FC1'), -(305,27,NULL,NULL,'St',NULL,'STEP','pl','Kroki','Mityng koncentruje się na dyskusji nad Dwunastoma Krokami Anonimowych Narkomanów.','FC1'), -(306,28,NULL,NULL,'Ti',NULL,NULL,'pl','Licznik czasu','Na tym mitngu czas wypowiedzi jest kontrolowany przez licznik czasu.','FC1'), -(307,29,NULL,NULL,'To',NULL,'TOP','pl','Dowolny temat','Temat tego mityngu jest wybierany przez spikera lub przez sumienie grupy.','FC1'), -(308,30,NULL,NULL,'Tr',NULL,'TRAD','pl','Tradycje','Mityng koncentruje się na dyskusji nad Dwunastoma Tradycjami NA.','FC1'), -(309,31,NULL,NULL,'TW',NULL,'TRAD','pl','Warsztaty z tradycji','Mityng koncentruje się na wnikliwej analizje jednej lub wielu z Dwunastu Tradycji Anonimowych Narkomanów','FC1'), -(310,32,NULL,NULL,'W',NULL,'W','pl','Kobiety','Mityng przeznaczony jedynie dla kobiet.','FC3'), -(311,33,NULL,NULL,'WC',NULL,'WCHR','pl','Wózki inwalidzkie','Mityng wyposażony w łatwy dostęp dla wózków inwalidzkich.','FC2'), -(312,34,NULL,NULL,'YP',NULL,'Y','pl','Młodzi ludzie','Mityng koncentruje się na dyskusjach nad potrzebami najmłodszych członków NA.','FC3'), -(313,35,NULL,NULL,'OE',NULL,NULL,'pl','Bez końca','Mityng bez ustalonej długości. Trwa tak długo, jak długo są na nim uczestnicy.','FC1'), -(314,36,NULL,NULL,'BK',NULL,'LIT','pl','Analiza książek','Analiza oficjalnych książek Anonimowych Narkomanów','FC1'), -(315,37,NULL,NULL,'NS',NULL,'NS','pl','Zakac palenia','Palenie w trakcie tego mityngu jest zabronione.','FC1'), -(316,38,NULL,NULL,'Ag',NULL,NULL,'pl','Agnostycy','Mityng dla ludzi o zróżnicowanych stopniach wiary.','FC1'), -(317,39,NULL,NULL,'FD',NULL,NULL,'pl','Piąty i dziesiąty krok','Dyskusja nad piątym i dziesiątym krokiem Anonimowych Narkomanów','FC1'), -(318,40,NULL,NULL,'AB',NULL,'QA','pl','Temat z koszyka','Temat mityngu wybierany jest spośród zaproponowanych niejawnie przez grupę.','FC1'), -(319,41,NULL,NULL,'ME',NULL,'MED','pl','Medytacja','Uczestnicy tego mityngu zachęcani są do wzięcia udziału w cichej medytacji.','FC1'), -(320,42,NULL,NULL,'RA',NULL,'RA','pl','Ograniczone uczestnictwo','Miejsce odbywania się mityngu nakłada ograniczenia na to, kto może wziąć udział w mityngu.','FC3'), -(321,43,NULL,NULL,'QA',NULL,'QA','pl','Pytania i odpowiedzi','Uczestnicy mogą zadawać pytania i oczekiwać odpowiedzi od innych uczestników.','FC1'), -(322,44,NULL,NULL,'CW',NULL,'CW','pl','Dzieci mile widziane','Dzieci są mile widziane.','FC3'), -(323,45,NULL,NULL,'CP',NULL,'CPT','pl','Koncepcje','Mityng koncentruje się na dyskusji nad Dwunastoma Koncepcjami Anonimowych Narkomanów.','FC1'), -(324,46,NULL,NULL,'FIN',NULL,'LANG','pl','Fiński','Mityng odbywa się w języku fińskim','LANG'), -(325,47,NULL,NULL,'ENG',NULL,'LANG','pl','Anglojęzyczny','Mityng odbywa się w języku angielskim.','LANG'), -(326,48,NULL,NULL,'PER',NULL,'LANG','pl','Perski','Mityng odbywa się w języku perskim','LANG'), -(327,49,NULL,NULL,'L/R',NULL,'LANG','pl','Litewski/rosyjski','Mityng odbywa się w języku litewskim/rosyjskim','LANG'), -(328,51,NULL,NULL,'LC',NULL,'LC','pl','Życie w czystości','Mityng koncentruje się na dyskusji nad tekstem z \"Życie w czystości: Podróż trwa nadal\".','FC1'), -(329,52,NULL,NULL,'GP',NULL,'GP','pl','Guiding Principles','Mityng koncentruje się na dyskusji nad tekstem z \"Guiding Principles - The Spirit of Our Traditions\".','FC1'), -(330,54,NULL,NULL,'VM',NULL,'VM','pl','Virtual Meeting','Meets Virtually','FC2'), -(331,55,NULL,NULL,'TC',NULL,'TC','pl','Temporarily Closed Facility','Facility is Temporarily Closed','FC2'), -(332,56,NULL,NULL,'HY',NULL,'HYBR','pl','Hybrid Meeting','Meets Virtually and In-person','FC2'), -(333,1,NULL,NULL,'RC',NULL,'BEG','pt','Recém-chegados','Esta reunião tem foco nas necessidades de novos membros em NA.','FC3'), -(334,2,NULL,NULL,'BL',NULL,'LANG','pt','Bilíngue','Reunião pode acontecer em duas línguas além de Português.','LANG'), -(335,3,NULL,NULL,'TB',NULL,'BT','pt','Texto Básico','Esta reunião tem foco no debate sobre o Texto Básico de Narcóticos Anônimos.','FC1'), -(336,4,NULL,NULL,'F',NULL,'CLOSED','pt','Fechada','Esta reunião fechada para não adictos. Você deve ir apenas se acredita ter problemas com abuso de substâncias.','O'), -(337,5,NULL,NULL,'FF',NULL,'CH','pt','Fechada em feriados','Esta reunião acontece em local que geralmente é fechado em feirados.','FC3'), -(338,6,NULL,NULL,'VL',NULL,'CAN','pt','Luz de velas','Esta reunião acontece à luz de velas.','FC2'), -(339,7,NULL,NULL,'CA',NULL,'','pt','Criança sob supervisão','Bem-comportadas, crianças sob supervisão são bem-vindas.','FC3'), -(340,8,NULL,NULL,'D',NULL,'DISC','pt','Discussão','Esta reunião convida a participação de todos.','FC1'), -(341,9,NULL,NULL,'ES',NULL,'LANG','pt','Espanhol','Esta reunião acontece em Espanhol.','LANG'), -(342,10,NULL,NULL,'LGBT',NULL,'GL','pt','LGBTQ+','Reunião de interesse LGBTQ+ em NA.','FC3'), -(343,11,NULL,NULL,'DC',NULL,NULL,'pt','Doença Crônica','Esta reunião tem foco nos interesses especiais de pessoas sofrendo de doenças crônicas.','FC1'), -(344,12,NULL,NULL,'IP',NULL,'PI','pt','Panfleto Informativo','Esta reunião tem foco na discussão sobre um ou mais IPs ou Panfletos Informativos.','FC1'), -(345,13,NULL,NULL,'FUN',NULL,'IW','pt','Funciona - Como e Por quê','Esta reunião tem foco na discussão do texto do livro Funciona - Como e Por quê.','FC1'), -(346,14,NULL,NULL,'SPH',NULL,'JFT','pt','Só Por Hoje','Esta reunião tem foco na discussão do texto do livro Só Por Hoje.','FC1'), -(347,15,NULL,NULL,'H',NULL,'M','pt','Homens','Reunião de interesse masculino em NA','FC3'), -(348,16,NULL,NULL,'PC',NULL,'NC','pt','Proibido crianças','Por gentileza não trazer crianças a essa reunião.','FC3'), -(349,17,NULL,NULL,'A',NULL,'OPEN','pt','Aberta','Esta reunião é aberta para adictos e não-adictos. Todos são bem-vindos.','O'), -(350,18,NULL,NULL,'Ind',NULL,NULL,'pt','Indicação','Esta reunião tem um formato que consiste que cada pessoa que partilha escolhe a próxima pessoa a partilhar.','FC1'), -(351,19,NULL,NULL,'FR',NULL,'VAR','pt','Formato Rotativo','Esta reunião muda seu formato a cada reunião.','FC1'), -(352,20,NULL,NULL,'Rr',NULL,NULL,'pt','Round Robin','Esta reunião tem um formato fixo de partilha (geralmente em círculo.)','FC1'), -(353,21,NULL,NULL,'CV',NULL,NULL,'pt','Câmera de vigilância','Esta reunião acontece em ambiente que tem câmeras de vigilância.','FC2'), -(354,22,NULL,NULL,'TD',NULL,'S-D','pt','Temática/Discussão','Esta reunião tem um orador, em seguida é aberta a participação dos membros','FC1'), -(355,23,NULL,NULL,'EP',NULL,'SWG','pt','Estudo de Passos','Esta reunião é de estudo dos passos através do Guia Para Trabalhar os Passos de NA.','FC1'), -(356,24,NULL,NULL,'LS',NULL,NULL,'pt','LSB','Esta reunião acontece com ajuda de intérprete de LIBRAS (Língua Brasileira de Sinais).','FC2'), -(357,26,NULL,NULL,'TM',NULL,'SPK','pt','Temática','Esta reunião é do tipo temática. Não há participação dos membros na discussão.','FC1'), -(358,27,NULL,NULL,'PS',NULL,'STEP','pt','Passos','Esta reunião é de discussão dos 12 Passos de NA.','FC1'), -(359,28,NULL,NULL,'TP',NULL,NULL,'pt','Tempo de Partilha','Esta reunião tem seu tempo de partilha controlado por relógio.','FC1'), -(360,29,NULL,NULL,'To',NULL,'TOP','pt','Tópico','Esta reunião é baseada em tópico escolhida por um orador ou por consciência de grupo.','FC1'), -(361,30,NULL,NULL,'Tr',NULL,'TRAD','pt','Tradições','Esta reunião tem foco em discussão das 12 Tradições de NA.','FC1'), -(362,31,NULL,NULL,'TW',NULL,'TRAD','pt','Workshop de Tradições','Esta reunião envolve uma discussão mais detalhada de uma ou mais das Tradições de N.A.','FC1'), -(363,32,NULL,NULL,'M',NULL,'W','pt','Mulheres','Reunião de interesse feminino em NA.','FC3'), -(364,33,NULL,NULL,'CadT',NULL,'WCHR','pt','Cadeirante Total','Esta reunião tem acesso total a cadeirantes.','FC2'), -(365,34,NULL,NULL,'Jv',NULL,'Y','pt','Jovens','Esta reunião tem foco nos interesses de membros jovens em NA.','FC3'), -(366,35,NULL,NULL,'UP',NULL,NULL,'pt','Último Partilhar','Sem duração fixa. A reunião continua até todos os presentes partilharem.','FC1'), -(367,36,NULL,NULL,'EL',NULL,'LIT','pt','Estudo de Literatura','Reunião de estudo de literaturas aprovadas de NA','FC1'), -(368,37,NULL,NULL,'NF',NULL,'NS','pt','Proibido Fumar','Não é permitido fumar nessa reunião.','FC1'), -(369,38,NULL,NULL,'Ag',NULL,NULL,'pt','Agnóstico','Destinada a pessoas com diferentes graus de fé.','FC1'), -(370,39,NULL,NULL,'QD',NULL,NULL,'pt','Quinto e Décimo','Reunião de discussão sobre o Quinto e Décimo Passos','FC1'), -(371,40,NULL,NULL,'ST',NULL,'QA','pt','Sorteio de Tópico','Um tópico é escolhido através de sugestões sorteadas.','FC1'), -(372,41,NULL,NULL,'ME',NULL,'MED','pt','Meditação','Esta reunião incentiva seus participantes a se envolverem em meditação silenciosa.','FC1'), -(373,42,NULL,NULL,'AR',NULL,'RA','pt','Acesso Restrito','Esta reunião esta em local que impõe restrição de acesso às pessoas.','FC3'), -(374,43,NULL,NULL,'PR',NULL,'QA','pt','Perguntas e Respostas','Os participantes podem fazer perguntas e esperar respostas dos membros do grupo.','FC1'), -(375,44,NULL,NULL,'PC',NULL,'CW','pt','Permitido Crianças','Crianças são bem-vindas a essa reunião.','FC3'), -(376,45,NULL,NULL,'Con',NULL,'CPT','pt','Conceitos','Esta reunião tem foco na discussão dos Doze Conceitos de NA.','FC1'), -(377,46,NULL,NULL,'FIN',NULL,'LANG','pt','Filandês','Reunião em língua filandesa','LANG'), -(378,47,NULL,NULL,'ENG',NULL,'LANG','pt','Inglês','Reunião em língua inglesa.','LANG'), -(379,48,NULL,NULL,'PER',NULL,'LANG','pt','Persa','Reunião em língua persa','LANG'), -(380,49,NULL,NULL,'L/R',NULL,'LANG','pt','Lituano/Russo','Reunião em Lituano/Russo','LANG'), -(381,51,NULL,NULL,'VL',NULL,'LC','pt','Vivendo Limpo','Esta é uma reunião de discussão do livro Vivendo Limpo-A Jornada Continua.','FC1'), -(382,52,NULL,NULL,'GP',NULL,'GP','pt','Guia de Princípios','Esta é uma reunião baseada no livro Guia de Princípios - O Espírito das Nossas Tradições .','FC1'), -(383,53,NULL,NULL,'CadP',NULL,'WCHR','pt','Cadeirante Parcial','Esta reunião tem acesso parcial a cadeirante.','FC2'), -(384,54,NULL,NULL,'VM',NULL,'VM','pt','Virtual Meeting','Meets Virtually','FC2'), -(385,55,NULL,NULL,'TC',NULL,'TC','pt','Temporarily Closed Facility','Facility is Temporarily Closed','FC2'), -(386,56,NULL,NULL,'HY',NULL,'HYBR','pt','Hybrid Meeting','Meets Virtually and In-person','FC2'), -(387,1,NULL,NULL,'B',NULL,'BEG','ru','Начинающие','Эта встреча посвящена потребностям новых членов NA.','FC3'), -(388,2,NULL,NULL,'BL',NULL,'LANG','ru','Двуязычное','На этом совещании могут присутствов Базового Текста Анонимных Наркоманов','LANG'), -(389,4,NULL,NULL,'C',NULL,'CLOSED','ru','Закрытая','Эта встреча закрыта для не наркоманов. Вам следует присутствовать только в том случае, если вы считаете, что у вас могут быть проблемы со злоупотреблением психоактивными веществами.','O'), -(390,5,NULL,NULL,'CH',NULL,'CH','ru','Закрыто по праздникам','Эта встреча собирается в учреждении, которое обычно закрыто в праздничные дни.','FC3'), -(391,6,NULL,NULL,'CL',NULL,'CAN','ru','Искусственное освещение','Эта встреча проводится при свечах.','FC2'), -(392,7,NULL,NULL,'CS',NULL,'','ru','Дети под присмотром','Добро пожаловать, хорошо воспитанные дети приветствуются.','FC3'), -(393,8,NULL,NULL,'D',NULL,'DISC','ru','Обсуждение','Эта встреча приглашает к участию всех участников.','FC1'), -(394,9,NULL,NULL,'ES',NULL,'LANG','ru','Испанский','Эта встреча проводится на испанском языке.','LANG'), -(395,10,NULL,NULL,'GL',NULL,'GL','ru','Геи / Лесбиянки / трансгендеры','Эта встреча посвящена потребностям геев, лесбиянок и транссексуальных членов АН.','FC3'), -(396,11,NULL,NULL,'IL',NULL,NULL,'ru','Болезнь','Эта встреча посвящена потребностям членов АН с хроническим заболеванием.','FC1'), -(397,12,NULL,NULL,'IP',NULL,'IP','ru','Информационная брошюра','Эта встреча посвящена обсуждению одной или нескольких информационных брошюр.','FC1'), -(398,13,NULL,NULL,'IW',NULL,'IW','ru','Это работает - как и почему','Эта встреча посвящена обсуждению текста «Как это работает - как и почему».','FC1'), -(399,14,NULL,NULL,'JT',NULL,'JFT','ru','Только сегодня','Эта встреча посвящена обсуждению текста \"Только Сегодня\"','FC1'), -(400,15,NULL,NULL,'M',NULL,'M','ru','Мужчины','Эта встреча предназначена только для мужчин.','FC3'), -(401,16,NULL,NULL,'NC',NULL,'NC','ru','Без детей','Пожалуйста, не приводите детей на эту встречу.','FC3'), -(402,17,NULL,NULL,'O',NULL,'OPEN','ru','Открытая','Эта встреча открыта как для наркоманов, так и для не наркоманов. Все приветствуются.','O'), -(403,18,NULL,NULL,'Pi',NULL,NULL,'ru','Питч','Эта встреча имеет формат, который состоит из каждого участника, который разделяет выбор следующего участника.','FC1'), -(404,19,NULL,NULL,'RF',NULL,'VAR','ru','Ротация','Эта встреча имеет формат, который изменяется для каждой встречи.','FC1'), -(405,20,NULL,NULL,'Rr',NULL,NULL,'ru','Говорим по кругу','Эта встреча имеет фиксированный порядок обмена опытом (высказывания по кругу.)','FC1'), -(406,21,NULL,NULL,'SC',NULL,NULL,'ru','Камеры наблюдения','Эта встреча проводится в учреждении с камерами наблюдения.','FC2'), -(407,22,NULL,NULL,'SD',NULL,'S-D','ru','Спикерская / Обсуждение','Это спикерская, а затем время для обсуждений.','FC1'), -(408,23,NULL,NULL,'SG',NULL,'SWG','ru','Руководство по Шагам АН','Эта встреча посвящена обсуждению текста руководства по шагам АН.','FC1'), -(409,24,NULL,NULL,'SL',NULL,NULL,'ru','Для глухих','Эта встреча предоставляет переводчика американского языка жестов (ASL) для глухих.','FC2'), -(410,26,NULL,NULL,'So',NULL,'SPK','ru','Только спикерская','Только спикерская. Другие участники не участвуют в обсуждении.','FC1'), -(411,27,NULL,NULL,'St',NULL,'STEP','ru','Шаги','Эта встреча посвящена обсуждению Двенадцати Шагов АН.','FC1'), -(412,28,NULL,NULL,'Ti',NULL,NULL,'ru','Таймер','Время этой встречи ограничено таймером.','FC1'), -(413,29,NULL,NULL,'To',NULL,'TOP','ru','Тема','Эта встреча основана на теме, выбранной ведущим или групповым.','FC1'), -(414,30,NULL,NULL,'Tr',NULL,'TRAD','ru','Традиции','Эта встреча посвящена обсуждению Двенадцати Традиций АН.','FC1'), -(415,31,NULL,NULL,'TW',NULL,'TRAD','ru','Мастерская Традиций','Эта встреча включает в себя подробное обсуждение одной или нескольких из двенадцати традиций А.Н.','FC1'), -(416,32,NULL,NULL,'W',NULL,'W','ru','Женская','Эта встреча предназначена для участия только женщин.','FC3'), -(417,33,NULL,NULL,'WC',NULL,'WCHR','ru','Инвалидное кресло','Эта встреча доступна для инвалидов.','FC2'), -(418,34,NULL,NULL,'YP',NULL,'Y','ru','Молодые люди','Эта встреча ориентирована на потребности молодых членов АН.','FC3'), -(419,35,NULL,NULL,'OE',NULL,NULL,'ru','Неограниченная','Нет фиксированной продолжительности. Встреча продолжается до тех пор, пока все присутствующие не смогут поделиться опытом.','FC1'), -(420,36,NULL,NULL,'BK',NULL,'LIT','ru','Книжное обучение','Утвержденные книги А.Н.','FC1'), -(421,37,NULL,NULL,'NS',NULL,'NS','ru','Не курить','Курение запрещено на этой встрече.','FC1'), -(422,38,NULL,NULL,'Ag',NULL,NULL,'ru','Агностики','Предназначен для людей с разной степенью веры.','FC1'), -(423,39,NULL,NULL,'FD',NULL,NULL,'ru','Пятый и Десятый','Обсуждение пятого шага и десятого шага','FC1'), -(424,40,NULL,NULL,'AB',NULL,'QA','ru','Коробочка','Тема выбирается из предложений, помещенных в коробочку.','FC1'), -(425,41,NULL,NULL,'ME',NULL,'MED','ru','Медитация','Эта встреча поощряет ее участников заниматься тихой медитацией.','FC1'), -(426,42,NULL,NULL,'RA',NULL,'RA','ru','Ограниченная Посещаемость','Эта встреча накладывает ограничения на посетителей.','FC3'), -(427,43,NULL,NULL,'QA',NULL,'QA','ru','Вопрос и ответ','Участники могут задавать вопросы и ожидать ответов от членов группы.','FC1'), -(428,44,NULL,NULL,'CW',NULL,'CW','ru','Дети - добро пожаловать','Дети приветствуются на этой встрече.','FC3'), -(429,45,NULL,NULL,'CP',NULL,'CPT','ru','Концепции','Эта встреча посвящена обсуждению двенадцати концепций А.Н.','FC1'), -(430,46,NULL,NULL,'FIN',NULL,'LANG','ru','Финский','финноязычная встреча','LANG'), -(431,47,NULL,NULL,'ENG',NULL,'LANG','ru','Англогоязычный','На его собрании могут присутствовать носители английского языка.','LANG'), -(432,48,NULL,NULL,'PER',NULL,'LANG','ru','Персидский','Собрание проводится на Персидском языке','LANG'), -(433,49,NULL,NULL,'L/R',NULL,'LANG','ru','Русский\\литовский','Русскоговорящие собрания АН','LANG'), -(434,51,NULL,NULL,'LC',NULL,'LC','ru','Жить Чистыми','Это обсуждение книги АН «Живи чисто - путешествие продолжается».','FC1'), -(435,52,NULL,NULL,'GP',NULL,'GP','ru','Руководящие принципы','Это обсуждение книги АН «Руководящие принципы - дух наших традиций».','FC1'), -(436,54,NULL,NULL,'VM',NULL,'VM','ru','Виртуальная встреча','Собираемся онлайн','FC2'), -(437,55,NULL,NULL,'TC',NULL,'TC','ru','Временно закрыто','Объект временно закрыт','FC2'), -(438,56,NULL,NULL,'HY',NULL,'HYBR','ru','Hybrid Meeting','Meets Virtually and In-person','FC2'), -(439,4,NULL,NULL,'S',NULL,'CLOSED','sv','Slutet möte','Ett slutet NA möte är för de individer som identifierar sig som beroende eller för de som är osäkra och tror att de kanske har drogproblem.','FC3'), -(440,15,NULL,NULL,'M',NULL,'M','sv','Mansmöte','Detta möte är endast öppet för män.','FC3'), -(441,17,NULL,NULL,'Ö',NULL,'OPEN','sv','Öppet möte','Ett öppet möte är ett NA-möte där vem som helst som är intresserad av hur vi har funnit tillfrisknande från beroendesjukdomen kan närvara.','FC3'), -(442,47,NULL,NULL,'ENG',NULL,NULL,'sv','Engelska','Engelsktalande möte','FC3'), -(443,48,NULL,NULL,'PER',NULL,NULL,'sv','Persiskt','Persiskt möte','FC1'), -(444,32,NULL,NULL,'K',NULL,'W','sv','Kvinnomöte','Detta möte är endast öppet för kvinnor.','FC3'), -(445,33,NULL,NULL,'RL',NULL,'WCHR','sv','Rullstolsvänlig lokal','Detta möte är tillgängligt för rullstolsbundna.','FC2'), -(446,47,NULL,NULL,'ENG',NULL,NULL,'sv','Engelska','Engelsktalande möte','FC3'), -(447,54,NULL,NULL,'VM',NULL,'VM','sv','Virtual Meeting','Meets Virtually','FC2'), -(448,55,NULL,NULL,'TC',NULL,'TC','sv','Temporarily Closed Facility','Facility is Temporarily Closed','FC2'), -(449,56,NULL,NULL,'HY',NULL,'HYBR','sv','Hybrid Meeting','Meets Virtually and In-person','FC2'), -(450,1,NULL,NULL,'B',NULL,'BEG','fa','تازه واردان','این جلسه بر روی نیازهای تازه واردان در معتادان گمنام متمرکز میباشد','FC3'), -(451,2,NULL,NULL,'BL',NULL,'LANG','fa','دو زبانه','این جلسه پذیرای شرکت کنندگان انگلیسی زبان و دیگر زبان ها میباشد','LANG'), -(452,3,NULL,NULL,'BT',NULL,'BT','fa','کتاب پایه','این جلسه متمرکز بر روی بحث درباره کتاب پایه معتادان گمنام میباشد','FC1'), -(453,4,NULL,NULL,'C',NULL,'CLOSED','fa','بسته','این جلسه برای افراد غیر معتاد بسته میباشد. شما تنها اگر فکر میکنید با مواد خدر مشکل دارید میتوانید شرکت کنید','O'), -(454,5,NULL,NULL,'CH',NULL,'CH','fa','بسته در روزهای تعطیل','این جلسات در روزهای تعطیل برگزار نمیگردد','FC3'), -(455,6,NULL,NULL,'CL',NULL,'CAN','fa','شمع روشن','این جلسه بهمراه شمع روشن برگزار میگردد','FC2'), -(456,7,NULL,NULL,'CS',NULL,'','fa','کودکان بی سرپرست','خوش رفتاری','FC3'), -(457,8,NULL,NULL,'D',NULL,'DISC','fa','بحث و گفتگو','این جلسه از تمامی شرکت کنندگان دعوت به بحث میکند','FC1'), -(458,9,NULL,NULL,'ES',NULL,'LANG','fa','اسپانیایی','این جلسه به زبان اسپانیایی برگزار میگردد','LANG'), -(459,10,NULL,NULL,'GL',NULL,'GL','fa','مردان همجنس باز/زنان همجنس باز/تغییر جنسیتی ها','این جلسه به نیازهای همجنس بازان/همجنس خواهان میپردازد','FC3'), -(460,11,NULL,NULL,'IL',NULL,NULL,'fa','بیماران','این جلسه به نیازهای اعضا با بیماری های مزمن متمرکز میباشد','FC1'), -(461,12,NULL,NULL,'IP',NULL,'IP','fa','پمفلت های اطلاعاتی','این جلسه به بررسی و بحث در مورد یک یا چند پمفلت متمرکز میباشد','FC1'), -(462,13,NULL,NULL,'IW',NULL,'IW','fa','چگونگی عملکرد','این جلسه با موضوع بحث در مورد کتاب چگونگی عملکرد برگزار میگردد','FC1'), -(463,14,NULL,NULL,'JT',NULL,'JFT','fa','فقط برای امروز','این جلسه با موضوع بحث درمورد کتاب فقط برای امروز متمرکز میباشد','FC1'), -(464,15,NULL,NULL,'M',NULL,'M','fa','مردان','این جلسه فقط مخصوص آقایان مباشد','FC3'), -(465,16,NULL,NULL,'NC',NULL,'NC','fa','ممنوعیت ورود کودکان','لطفاً کودکان را به این جلسه نیاورید','FC3'), -(466,17,NULL,NULL,'O',NULL,'OPEN','fa','باز','این جلسه برای کلیه اعضا معتاد و همچنین غیر معتادان باز میباشد','O'), -(467,18,NULL,NULL,'Pi',NULL,NULL,'fa','انتخابی','فورمت این جلسه بصورتیست که هر مشارکت کننده میتواند نفر بعدی را جهت مشارکت انتخاب نماید','FC1'), -(468,19,NULL,NULL,'RF',NULL,'VAR','fa','فورمت چرخشی','فورمت این جلسه در هر جلسه متغیر میباشد','FC1'), -(469,20,NULL,NULL,'Rr',NULL,NULL,'fa','مشارکت موضوع دار','این جلسه دارای یکسری موضوعات خاص میباشد (معمولاً بصورت چرخشی)','FC1'), -(470,21,NULL,NULL,'SC',NULL,NULL,'fa','دوربین مداربسته','این جلسه در مکانهای مجهز به دوربین مدار بسته برگزار میگردد','FC2'), -(471,22,NULL,NULL,'SD',NULL,'S-D','fa','سخنرانی/بحث','این جلسه توسط یک سخنران گردانندگی میگردد','FC1'), -(472,23,NULL,NULL,'SG',NULL,'SWG','fa','راهنمای کارکرد قدم','این جلسه با موضوع بررسی و بحث در مورد کتاب راهنمای کاکرد قدم برگزار میگردد','FC1'), -(473,24,NULL,NULL,'SL',NULL,NULL,'fa','تفسیر به زبان انگلیسی برای ناشنوایان','این جلسه بهمراه مفسر انگلیسی برای ناشنوایان برگزار میگردد','FC2'), -(474,26,NULL,NULL,'So',NULL,'SPK','fa','فقط سخنرانی','این جلسه فقط یک سخنران دارد. دیگر شرکت کنندگان حق مشارکت ندارند','FC1'), -(475,27,NULL,NULL,'St',NULL,'STEP','fa','قدم','این جلسه با موضوع بحث درمورد قدم های دوازده گانه معتادان گمنام برگزار میگردد','FC1'), -(476,28,NULL,NULL,'Ti',NULL,NULL,'fa','زمان سنج','در این جلسه زمان مشارکت توسط زمان سنج محاسبه و کنترل میگردد','FC1'), -(477,29,NULL,NULL,'To',NULL,'TOP','fa','موضوع','این جلسه برپایه موضوع انتخابی توسط یک سخنران یا وجدان گروهی برگزار میگردد','FC1'), -(478,30,NULL,NULL,'Tr',NULL,'TRAD','fa','سنت ها','این جلسه با موضوع بحث درمورد سنت های دوازده گانه معتادان گمنام برگزار میگردد','FC1'), -(479,31,NULL,NULL,'TW',NULL,'TRAD','fa','کارگاه سنت ها','این جلسه با موضوع بررسی جزئیاتی یک یاچند سنت معتادان گمنام برگزار میگردد','FC1'), -(480,32,NULL,NULL,'W',NULL,'W','fa','بانوان','این جلسه فقط مخصوص خانم ها مباشد','FC3'), -(481,33,NULL,NULL,'WC',NULL,'WCHR','fa','ویلچر','در این جلسه ویلچر در دسترس میباشد','FC2'), -(482,34,NULL,NULL,'YP',NULL,'Y','fa','جوانان','این جلسه بر روی نیازهای اعضا جوان متمرکز میباشد','FC3'), -(483,35,NULL,NULL,'OE',NULL,NULL,'fa','بی پایان','بدون مدت زمان ثابت. این جلسه تا زمانی که تمامی اعضا درخواست کننده مشارکت، مشارکت نکرده باشند به اتمام نمیرسد','FC1'), -(484,36,NULL,NULL,'BK',NULL,'LIT','fa','کتاب خوانی','کتابخوانی نشریات معتادان گمنام','FC1'), -(485,37,NULL,NULL,'NS',NULL,'NS','fa','مصرف دخانیات ممنوع','مصرف دخانیات در این جلسه ممنوع میباشد','FC1'), -(486,38,NULL,NULL,'Ag',NULL,NULL,'fa','بی اعتقادان','جلسه مخصوص اعضا باهر میزان درجه از اعتقاد','FC1'), -(487,39,NULL,NULL,'FD',NULL,NULL,'fa','پنج و ده','جلسه بحث و بررسی قدم های پنج و ده','FC1'), -(488,40,NULL,NULL,'AB',NULL,'QA','fa','انتخاب موضوع از سبد','انتخاب یک موضوع توسط پیشنهادات ارائه شده در سبد','FC1'), -(489,41,NULL,NULL,'ME',NULL,'MED','fa','مراقبه','این جلسه اعضا شرکت کننده را به مراقبه کامل تشویق مینماید','FC1'), -(490,42,NULL,NULL,'RA',NULL,'RA','fa','محدودیت شرکت کننده','این جلسه دارای محدودیت شرکت کنندگان میباشد','FC3'), -(491,43,NULL,NULL,'QA',NULL,'QA','fa','پرسش و پاسخ','اعضا میتوانند سوالات خود را مطرح نموده و منتظر دریافت پاسخ از دیگر اعضا باشند','FC1'), -(492,44,NULL,NULL,'CW',NULL,'CW','fa','با حضور کودکان','حضور کودکان در این جلسه بلامانع میباشد','FC3'), -(493,45,NULL,NULL,'CP',NULL,'CPT','fa','مفاهیم','این جلسه با موضوع بحث درمورد مفاهیم دوازده گانه معتادان گمنام برگزار میگردد','FC1'), -(494,46,NULL,NULL,'FIN',NULL,'LANG','fa','فنلاندی','جلسه به زبان فنلاندی','LANG'), -(495,47,NULL,NULL,'ENG',NULL,'LANG','fa','انگلیسی','این جلسه میتواند با حضور اعضا انگلیسی زبان نیز برگزار گردد','LANG'), -(496,48,NULL,NULL,'PER',NULL,'LANG','fa','فارسی','جلسه به زبان فارسی','LANG'), -(497,49,NULL,NULL,'L/R',NULL,'LANG','fa','لیتوانیایی/روسی','جلسه به زبان های لیتوانیایی/روسی','LANG'), -(498,51,NULL,NULL,'LC',NULL,'LC','fa','پاک زیستن','این جلسه با موضوع بررسی و بحث در مورد کتاب پاک زیستن - سفر ادامه دارد، برگزار میگردد','FC1'), -(499,52,NULL,NULL,'GP',NULL,'GP','fa','روح سنت ها','این جلسه با موضوع بررسی و بحث در مورد کتاب روح سنت ها برگزار میگردد','FC1'); -/*!40000 ALTER TABLE `na_comdef_formats` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `na_comdef_meetings_data` --- - -DROP TABLE IF EXISTS `na_comdef_meetings_data`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `na_comdef_meetings_data` ( - `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, - `meetingid_bigint` bigint(20) unsigned NOT NULL, - `key` varchar(32) NOT NULL, - `field_prompt` varchar(255) DEFAULT NULL, - `lang_enum` varchar(7) DEFAULT NULL, - `visibility` int(11) DEFAULT NULL, - `data_string` varchar(255) DEFAULT NULL, - `data_bigint` bigint(20) DEFAULT NULL, - `data_double` double DEFAULT NULL, - PRIMARY KEY (`id`), - KEY `data_bigint` (`data_bigint`), - KEY `data_double` (`data_double`), - KEY `meetingid_bigint` (`meetingid_bigint`), - KEY `lang_enum` (`lang_enum`), - KEY `key` (`key`), - KEY `visibility` (`visibility`), - FULLTEXT KEY `na_comdef_meetings_data_data_string_fulltext` (`data_string`) -) ENGINE=InnoDB AUTO_INCREMENT=24 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `na_comdef_meetings_data` --- - -LOCK TABLES `na_comdef_meetings_data` WRITE; -/*!40000 ALTER TABLE `na_comdef_meetings_data` DISABLE KEYS */; -INSERT INTO `na_comdef_meetings_data` VALUES -(1,0,'meeting_name','Meeting Name','en',0,'Meeting Name',NULL,NULL), -(2,0,'location_text','Location Name','en',0,'Location Name',NULL,NULL), -(3,0,'location_info','Additional Location Information','en',0,'Additional Location Information',NULL,NULL), -(4,0,'location_street','Street Address','en',0,'Street Address',NULL,NULL), -(5,0,'location_city_subsection','Borough','en',0,'Borough',NULL,NULL), -(6,0,'location_neighborhood','Neighborhood','en',0,'Neighborhood',NULL,NULL), -(7,0,'location_municipality','Town','en',0,'Town',NULL,NULL), -(8,0,'location_sub_province','County','en',0,'County',NULL,NULL), -(9,0,'location_province','State','en',0,'State',NULL,NULL), -(10,0,'location_postal_code_1','Zip Code','en',0,NULL,0,NULL), -(11,0,'location_nation','Nation','en',0,'Nation',NULL,NULL), -(12,0,'comments','Comments','en',0,'Comments',NULL,NULL), -(13,0,'train_lines','Train Lines','en',0,NULL,NULL,NULL), -(14,0,'bus_lines','Bus Lines','en',0,NULL,NULL,NULL), -(15,0,'contact_phone_2','Contact 2 Phone','en',1,'Contact 2 Phone',NULL,NULL), -(16,0,'contact_email_2','Contact 2 Email','en',1,'Contact 2 Email',NULL,NULL), -(17,0,'contact_name_2','Contact 2 Name','en',1,'Contact 2 Name',NULL,NULL), -(18,0,'contact_phone_1','Contact 1 Phone','en',1,'Contact 1 Phone',NULL,NULL), -(19,0,'contact_email_1','Contact 1 Email','en',1,'Contact 1 Email',NULL,NULL), -(20,0,'contact_name_1','Contact 1 Name','en',1,'Contact 1 Name',NULL,NULL), -(21,0,'phone_meeting_number','Phone Meeting Dial-in Number','en',0,'Phone Meeting Dial-in Number',NULL,NULL), -(22,0,'virtual_meeting_link','Virtual Meeting Link','en',0,'Virtual Meeting Link',NULL,NULL), -(23,0,'virtual_meeting_additional_info','Virtual Meeting Additional Info','en',0,'Virtual Meeting Additional Info',NULL,NULL); -/*!40000 ALTER TABLE `na_comdef_meetings_data` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `na_comdef_meetings_longdata` --- - -DROP TABLE IF EXISTS `na_comdef_meetings_longdata`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `na_comdef_meetings_longdata` ( - `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, - `meetingid_bigint` bigint(20) unsigned NOT NULL, - `key` varchar(32) NOT NULL, - `field_prompt` varchar(255) DEFAULT NULL, - `lang_enum` varchar(7) DEFAULT NULL, - `visibility` int(11) DEFAULT NULL, - `data_blob` text DEFAULT NULL, - PRIMARY KEY (`id`), - KEY `meetingid_bigint` (`meetingid_bigint`), - KEY `lang_enum` (`lang_enum`), - KEY `field_prompt` (`field_prompt`), - KEY `key` (`key`), - KEY `visibility` (`visibility`), - FULLTEXT KEY `na_comdef_meetings_longdata_data_blob_fulltext` (`data_blob`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `na_comdef_meetings_longdata` --- - -LOCK TABLES `na_comdef_meetings_longdata` WRITE; -/*!40000 ALTER TABLE `na_comdef_meetings_longdata` DISABLE KEYS */; -/*!40000 ALTER TABLE `na_comdef_meetings_longdata` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `na_comdef_meetings_main` --- - -DROP TABLE IF EXISTS `na_comdef_meetings_main`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `na_comdef_meetings_main` ( - `id_bigint` bigint(20) unsigned NOT NULL AUTO_INCREMENT, - `root_server_id` bigint(20) unsigned DEFAULT NULL, - `source_id` bigint(20) unsigned DEFAULT NULL, - `worldid_mixed` varchar(255) DEFAULT NULL, - `shared_group_id_bigint` bigint(20) DEFAULT NULL, - `service_body_bigint` bigint(20) unsigned NOT NULL, - `weekday_tinyint` tinyint(3) unsigned DEFAULT NULL, - `venue_type` tinyint(3) unsigned DEFAULT NULL, - `start_time` time DEFAULT NULL, - `duration_time` time DEFAULT NULL, - `time_zone` varchar(40) DEFAULT NULL, - `formats` varchar(255) DEFAULT NULL, - `lang_enum` varchar(7) DEFAULT NULL, - `longitude` double DEFAULT NULL, - `latitude` double DEFAULT NULL, - `published` tinyint(4) NOT NULL DEFAULT 0, - `email_contact` varchar(255) DEFAULT NULL, - PRIMARY KEY (`id_bigint`), - KEY `weekday_tinyint` (`weekday_tinyint`), - KEY `venue_type` (`venue_type`), - KEY `service_body_bigint` (`service_body_bigint`), - KEY `start_time` (`start_time`), - KEY `duration_time` (`duration_time`), - KEY `time_zone` (`time_zone`), - KEY `formats` (`formats`), - KEY `lang_enum` (`lang_enum`), - KEY `worldid_mixed` (`worldid_mixed`), - KEY `shared_group_id_bigint` (`shared_group_id_bigint`), - KEY `longitude` (`longitude`), - KEY `latitude` (`latitude`), - KEY `published` (`published`), - KEY `email_contact` (`email_contact`), - KEY `root_server_id_source_id` (`root_server_id`,`source_id`), - CONSTRAINT `na_comdef_meetings_main_root_server_id_foreign` FOREIGN KEY (`root_server_id`) REFERENCES `na_root_servers` (`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `na_comdef_meetings_main` --- - -LOCK TABLES `na_comdef_meetings_main` WRITE; -/*!40000 ALTER TABLE `na_comdef_meetings_main` DISABLE KEYS */; -/*!40000 ALTER TABLE `na_comdef_meetings_main` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `na_comdef_service_bodies` --- - -DROP TABLE IF EXISTS `na_comdef_service_bodies`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `na_comdef_service_bodies` ( - `id_bigint` bigint(20) unsigned NOT NULL AUTO_INCREMENT, - `root_server_id` bigint(20) unsigned DEFAULT NULL, - `source_id` bigint(20) unsigned DEFAULT NULL, - `name_string` varchar(255) NOT NULL, - `description_string` text NOT NULL, - `lang_enum` varchar(7) NOT NULL DEFAULT 'en', - `worldid_mixed` varchar(255) DEFAULT NULL, - `kml_file_uri_string` varchar(255) DEFAULT NULL, - `principal_user_bigint` bigint(20) unsigned DEFAULT NULL, - `editors_string` varchar(255) DEFAULT NULL, - `uri_string` varchar(255) DEFAULT NULL, - `sb_type` varchar(32) DEFAULT NULL, - `sb_owner` bigint(20) unsigned DEFAULT NULL, - `sb_owner_2` bigint(20) unsigned DEFAULT NULL, - `sb_meeting_email` varchar(255) NOT NULL, - PRIMARY KEY (`id_bigint`), - KEY `worldid_mixed` (`worldid_mixed`), - KEY `kml_file_uri_string` (`kml_file_uri_string`), - KEY `principal_user_bigint` (`principal_user_bigint`), - KEY `editors_string` (`editors_string`), - KEY `lang_enum` (`lang_enum`), - KEY `uri_string` (`uri_string`), - KEY `sb_type` (`sb_type`), - KEY `sb_owner` (`sb_owner`), - KEY `sb_owner_2` (`sb_owner_2`), - KEY `sb_meeting_email` (`sb_meeting_email`), - KEY `root_server_id_source_id` (`root_server_id`,`source_id`), - CONSTRAINT `na_comdef_service_bodies_root_server_id_foreign` FOREIGN KEY (`root_server_id`) REFERENCES `na_root_servers` (`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `na_comdef_service_bodies` --- - -LOCK TABLES `na_comdef_service_bodies` WRITE; -/*!40000 ALTER TABLE `na_comdef_service_bodies` DISABLE KEYS */; -/*!40000 ALTER TABLE `na_comdef_service_bodies` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `na_comdef_users` --- - -DROP TABLE IF EXISTS `na_comdef_users`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `na_comdef_users` ( - `id_bigint` bigint(20) unsigned NOT NULL AUTO_INCREMENT, - `user_level_tinyint` tinyint(3) unsigned NOT NULL DEFAULT 0, - `name_string` varchar(255) NOT NULL, - `description_string` text NOT NULL, - `email_address_string` varchar(255) NOT NULL, - `login_string` varchar(255) NOT NULL, - `password_string` varchar(255) NOT NULL, - `last_access_datetime` datetime NOT NULL DEFAULT '1970-01-01 00:00:00', - `lang_enum` varchar(7) NOT NULL DEFAULT 'en', - `owner_id_bigint` bigint(20) NOT NULL DEFAULT -1, - PRIMARY KEY (`id_bigint`), - UNIQUE KEY `login_string` (`login_string`), - KEY `user_level_tinyint` (`user_level_tinyint`), - KEY `email_address_string` (`email_address_string`), - KEY `last_access_datetime` (`last_access_datetime`), - KEY `lang_enum` (`lang_enum`), - KEY `owner_id_bigint` (`owner_id_bigint`) -) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `na_comdef_users` --- - -LOCK TABLES `na_comdef_users` WRITE; -/*!40000 ALTER TABLE `na_comdef_users` DISABLE KEYS */; -INSERT INTO `na_comdef_users` VALUES -(1,1,'Server Administrator','Main Server Administrator','','serveradmin','$2y$10$wwu/pk1IUY3X3ppzoJvDJ.EWqIgZ1A4qyZHCrFNaN0r9RLHagTZGG','1970-01-01 00:00:00','en',-1); -/*!40000 ALTER TABLE `na_comdef_users` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `na_migrations` --- - -DROP TABLE IF EXISTS `na_migrations`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `na_migrations` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `migration` varchar(255) NOT NULL, - `batch` int(11) NOT NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `na_migrations` --- - -LOCK TABLES `na_migrations` WRITE; -/*!40000 ALTER TABLE `na_migrations` DISABLE KEYS */; -INSERT INTO `na_migrations` VALUES -(1,'1900_01_01_000000_create_sessions_table',1), -(2,'1901_01_01_000000_legacy_migrations',1), -(3,'1902_01_01_000000_create_initial_schema',1), -(4,'1903_01_01_000000_innodb_db_version',1), -(5,'1904_01_01_000000_innodb_meetings_data',1), -(6,'1905_01_01_000000_innodb_meetings_longdata',1), -(7,'1906_01_01_000000_innodb_formats',1), -(8,'1907_01_01_000000_innodb_meetings_main',1), -(9,'1908_01_01_000000_innodb_service_bodies',1), -(10,'1909_01_01_000000_innodb_users',1), -(11,'1910_01_01_000000_innodb_changes',1), -(12,'1911_01_01_000000_trim_whitespace',1), -(13,'2019_12_14_000001_create_personal_access_tokens_table',1), -(14,'2023_05_16_223943_format_types',1), -(15,'2024_06_12_164303_fix_meeting_lang_enum',1), -(16,'2024_07_20_203802_fix_admin_user_owners',1); -/*!40000 ALTER TABLE `na_migrations` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `na_personal_access_tokens` --- - -DROP TABLE IF EXISTS `na_personal_access_tokens`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `na_personal_access_tokens` ( - `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, - `tokenable_type` varchar(255) NOT NULL, - `tokenable_id` bigint(20) unsigned NOT NULL, - `name` varchar(255) NOT NULL, - `token` varchar(64) NOT NULL, - `abilities` text DEFAULT NULL, - `last_used_at` timestamp NULL DEFAULT NULL, - `expires_at` timestamp NULL DEFAULT NULL, - `created_at` timestamp NULL DEFAULT NULL, - `updated_at` timestamp NULL DEFAULT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `na_personal_access_tokens_token_unique` (`token`), - KEY `na_personal_access_tokens_tokenable_type_tokenable_id_index` (`tokenable_type`,`tokenable_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `na_personal_access_tokens` --- - -LOCK TABLES `na_personal_access_tokens` WRITE; -/*!40000 ALTER TABLE `na_personal_access_tokens` DISABLE KEYS */; -/*!40000 ALTER TABLE `na_personal_access_tokens` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `na_root_server_statistics` --- - -DROP TABLE IF EXISTS `na_root_server_statistics`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `na_root_server_statistics` ( - `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, - `root_server_id` bigint(20) unsigned NOT NULL, - `num_zones` int(10) unsigned NOT NULL, - `num_regions` int(10) unsigned NOT NULL, - `num_areas` int(10) unsigned NOT NULL, - `num_groups` int(10) unsigned NOT NULL, - `num_total_meetings` int(10) unsigned NOT NULL, - `num_in_person_meetings` int(10) unsigned NOT NULL, - `num_virtual_meetings` int(10) unsigned NOT NULL, - `num_hybrid_meetings` int(10) unsigned NOT NULL, - `num_unknown_meetings` int(10) unsigned NOT NULL, - `is_latest` tinyint(1) NOT NULL, - `created_at` timestamp NULL DEFAULT NULL, - `updated_at` timestamp NULL DEFAULT NULL, - PRIMARY KEY (`id`), - KEY `na_root_server_statistics_root_server_id_foreign` (`root_server_id`), - KEY `is_latest` (`is_latest`), - KEY `is_latest_root_server_id` (`is_latest`,`root_server_id`), - CONSTRAINT `na_root_server_statistics_root_server_id_foreign` FOREIGN KEY (`root_server_id`) REFERENCES `na_root_servers` (`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `na_root_server_statistics` --- - -LOCK TABLES `na_root_server_statistics` WRITE; -/*!40000 ALTER TABLE `na_root_server_statistics` DISABLE KEYS */; -/*!40000 ALTER TABLE `na_root_server_statistics` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `na_root_servers` --- - -DROP TABLE IF EXISTS `na_root_servers`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `na_root_servers` ( - `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, - `source_id` bigint(20) unsigned NOT NULL, - `name` varchar(255) NOT NULL, - `url` varchar(255) NOT NULL, - `server_info` text DEFAULT NULL, - `last_successful_import` datetime DEFAULT NULL, - `created_at` timestamp NULL DEFAULT NULL, - `updated_at` timestamp NULL DEFAULT NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `na_root_servers` --- - -LOCK TABLES `na_root_servers` WRITE; -/*!40000 ALTER TABLE `na_root_servers` DISABLE KEYS */; -/*!40000 ALTER TABLE `na_root_servers` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `na_sessions` --- - -DROP TABLE IF EXISTS `na_sessions`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `na_sessions` ( - `id` varchar(255) NOT NULL, - `user_id` bigint(20) unsigned DEFAULT NULL, - `ip_address` varchar(45) DEFAULT NULL, - `user_agent` text DEFAULT NULL, - `payload` text NOT NULL, - `last_activity` int(11) NOT NULL, - PRIMARY KEY (`id`), - KEY `na_sessions_user_id_index` (`user_id`), - KEY `na_sessions_last_activity_index` (`last_activity`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `na_sessions` --- - -LOCK TABLES `na_sessions` WRITE; -/*!40000 ALTER TABLE `na_sessions` DISABLE KEYS */; -INSERT INTO `na_sessions` VALUES -('4lISohRRKEYSvJpxRYMw94j06dw6WNagcbJB9Gmo',NULL,'192.168.65.1','Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.6 Safari/605.1.15','YTo0OntzOjY6Il90b2tlbiI7czo0MDoiVk5Lc1BCUG9pNjJENXUxU0YwQXljYjFZbUJJdzlEajJFZTdNZzhxRyI7czo5OiJsYW5nX2VudW0iO3M6MjoiZW4iO3M6OToiX3ByZXZpb3VzIjthOjE6e3M6MzoidXJsIjtzOjMzOiJodHRwOi8vbG9jYWxob3N0OjgwMDAvbWFpbl9zZXJ2ZXIiO31zOjY6Il9mbGFzaCI7YToyOntzOjM6Im9sZCI7YTowOnt9czozOiJuZXciO2E6MDp7fX19',1732564880); -/*!40000 ALTER TABLE `na_sessions` ENABLE KEYS */; -UNLOCK TABLES; -/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; - -/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; -/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; -/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; -/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; -/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; -/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; -/*M!100616 SET NOTE_VERBOSITY=@OLD_NOTE_VERBOSITY */; - --- Dump completed on 2024-11-25 20:02:57 diff --git a/src/.nvmrc b/src/.nvmrc index f203ab89b..2bd5a0a98 100644 --- a/src/.nvmrc +++ b/src/.nvmrc @@ -1 +1 @@ -20.13.1 +22 diff --git a/src/.phpcs.xml b/src/.phpcs.xml index 4c3e1c9bd..f3f267b47 100644 --- a/src/.phpcs.xml +++ b/src/.phpcs.xml @@ -45,8 +45,5 @@ You can add specific global ignores to different rules here. --> - - - - + diff --git a/src/app.html b/src/app.html index af5bd9a22..71a963859 100644 --- a/src/app.html +++ b/src/app.html @@ -2,7 +2,7 @@ - + %sveltekit.head% diff --git a/src/app/ConfigBase.php b/src/app/ConfigBase.php new file mode 100644 index 000000000..6598fd398 --- /dev/null +++ b/src/app/ConfigBase.php @@ -0,0 +1,51 @@ + (int)$value, + Setting::TYPE_FLOAT => (float)$value, + Setting::TYPE_BOOL => filter_var($value, FILTER_VALIDATE_BOOLEAN), + Setting::TYPE_ARRAY => static::parseEnvArray($value), + default => $value, + }; + } + + private static function parseEnvArray($value): array + { + if (is_array($value)) { + return $value; + } + + $decoded = json_decode($value, true); + if (is_array($decoded)) { + return $decoded; + } + + if (is_string($value) && $value !== '') { + return array_map('trim', explode(',', $value)); + } + + return []; + } +} diff --git a/src/app/Console/Commands/AddTranslationKey.php b/src/app/Console/Commands/AddTranslationKey.php new file mode 100644 index 000000000..d05c66572 --- /dev/null +++ b/src/app/Console/Commands/AddTranslationKey.php @@ -0,0 +1,251 @@ +argument('key'); + $value = $this->argument('value'); + + if (!preg_match('/^[a-z][a-zA-Z0-9]*$/', $key)) { + $this->error("Invalid key format. Key must be in camelCase (start with lowercase letter, no underscores or spaces)."); + return 1; + } + + $langPath = resource_path('js/lang'); + $files = File::glob($langPath . '/*.ts'); + + $files = array_filter($files, fn($file) => basename($file) !== 'index.ts'); + + if (empty($files)) { + $this->error("No translation files found in {$langPath}"); + return 1; + } + + $this->info("Adding translation key '{$key}' to all language files..."); + + foreach ($files as $file) { + $this->processFile($file, $key, $value); + } + + $this->info("\n✓ Translation key '{$key}' added to all language files."); + if (!$this->option('force')) { + $this->info("Note: Non-English files have been marked with '// TODO: translate' comments."); + } + + return 0; + } + + private function processFile(string $filePath, string $key, string $value): void + { + $fileName = basename($filePath); + $content = File::get($filePath); + + $isEnglish = str_starts_with($fileName, 'en.'); + + $translationValue = $isEnglish ? $value : $value; + $comment = $isEnglish ? '' : ', // TODO: translate'; + + // Find the translations export (e.g., export const enTranslations = {) + if (!preg_match('/export const \w+Translations = \{/', $content, $matches, PREG_OFFSET_CAPTURE)) { + $this->error("Could not find translations export in {$fileName}"); + return; + } + + $exportStart = $matches[0][1] + strlen($matches[0][0]); + + $closingBracePos = $this->findClosingBrace($content, $exportStart); + + if ($closingBracePos === false) { + $this->error("Could not find closing brace for translations in {$fileName}"); + return; + } + + // Extract the translations section + $translationsContent = substr($content, $exportStart, $closingBracePos - $exportStart); + + // Parse existing keys + preg_match_all('/^\s*(\w+):/m', $translationsContent, $keyMatches); + $existingKeys = $keyMatches[1]; + + // Check if key already exists + if (in_array($key, $existingKeys)) { + if (!$this->option('force')) { + $this->warn(" {$fileName}: Key '{$key}' already exists, skipping. Use --force to overwrite."); + return; + } + // Remove the existing key so we can replace it + $this->removeExistingKey($translationsContent, $key, $exportStart, $closingBracePos, $content, $filePath, $value, $fileName, $isEnglish); + return; + } + + // Find insertion point (alphabetically, case-insensitive) + $insertAfterKey = null; + $insertBeforeKey = null; + + foreach ($existingKeys as $existingKey) { + if (strcasecmp($existingKey, $key) < 0) { + $insertAfterKey = $existingKey; + } else { + $insertBeforeKey = $existingKey; + break; + } + } + + // Create the new line + // escape single quotes and backslashes + $escapedValue = str_replace(['\\', "'"], ['\\\\', "\\'"], $translationValue); + + // Determine if we're inserting at the end (after last key) + // If so, don't add comma since it will be the new last item + $isLastItem = ($insertAfterKey && !$insertBeforeKey); + $commentForNewLine = $isLastItem && !$isEnglish ? ' // TODO: translate' : $comment; + + $newLine = " {$key}: '{$escapedValue}'{$commentForNewLine}"; + + // Find the position to insert + if ($insertBeforeKey) { + // Insert before the next key (add comma after if English, otherwise comment includes comma) + if (preg_match('/^\s*' . preg_quote($insertBeforeKey, '/') . ':/m', $translationsContent, $match, PREG_OFFSET_CAPTURE)) { + $insertPos = $match[0][1]; + $comma = $isEnglish ? ',' : ''; + $before = substr($translationsContent, 0, $insertPos); + $after = substr($translationsContent, $insertPos); + + if (trim($before) === '') { + // At the start - keep structure but ensure newline before first key + if (substr($after, 0, 1) === "\n") { + $after = substr($after, 1); + } + $updatedContent = "\n" . $newLine . $comma . "\n" . $after; + } else { + $updatedContent = $before . $newLine . $comma . "\n" . $after; + } + } else { + return; + } + } elseif ($insertAfterKey) { + // Insert after the previous key (at the end) + if (preg_match('/^\s*' . preg_quote($insertAfterKey, '/') . ':.*$/m', $translationsContent, $match, PREG_OFFSET_CAPTURE)) { + $lineStart = $match[0][1]; + $lineLen = strlen($match[0][0]); + $before = substr($translationsContent, 0, $lineStart); + $lastLine = substr($translationsContent, $lineStart, $lineLen); + $after = substr($translationsContent, $lineStart + $lineLen); + + // Ensure previous last line has trailing comma before any comment + if (!preg_match('/,\s*(?:\/\/.*)?$/', $lastLine)) { + if (preg_match('/(.*?)(\s*\/\/.*)$/', $lastLine, $m2)) { + $beforeComment = rtrim($m2[1]); + $commentPart = ltrim($m2[2]); + $lastLine = $beforeComment . ', ' . $commentPart; + } else { + $lastLine = rtrim($lastLine) . ','; + } + } + + $updatedContent = $before . $lastLine . "\n" . $newLine . $after; + } else { + return; + } + } else { + // No existing keys, add as first key + $updatedContent = "\n" . $newLine . "\n"; + } + + $newContent = substr($content, 0, $exportStart) + . $updatedContent + . substr($content, $closingBracePos); + + File::put($filePath, $newContent); + $this->info(" ✓ {$fileName}"); + } + + private function findClosingBrace(string $content, int $startPos): int|false + { + $depth = 1; + $length = strlen($content); + + for ($i = $startPos; $i < $length; $i++) { + if ($content[$i] === '{') { + $depth++; + } elseif ($content[$i] === '}') { + $depth--; + if ($depth === 0) { + return $i; + } + } + } + + return false; + } + + private function removeExistingKey( + string $translationsContent, + string $key, + int $exportStart, + int $closingBracePos, + string $content, + string $filePath, + string $value, + string $fileName, + bool $isEnglish + ): void { + // Find the line with the existing key and extract its value + $pattern = '/^(\s*)' . preg_quote($key, '/') . ':\s*([\'"])(.*?)\2(,?)(.*?)$/m'; + if (preg_match($pattern, $translationsContent, $match, PREG_OFFSET_CAPTURE)) { + $lineStart = $match[0][1]; + $indent = $match[1][0]; + $trailingComma = $match[4][0]; + + // Escape the new value + $escapedValue = str_replace(['\\', "'"], ['\\\\', "\\'"], $value); + + // Add TODO comment for non-English files + $comment = $isEnglish ? '' : ', // TODO: translate'; + + // If there's no comma, we need to add one (or use the comment's comma) + if (!$trailingComma && !$comment) { + $trailingComma = ','; + } elseif ($trailingComma && $comment) { + // Comment already has comma, don't duplicate + $trailingComma = ''; + } + + $newLine = "{$indent}{$key}: '{$escapedValue}'{$trailingComma}{$comment}"; + + // Replace the entire line + $beforeLine = substr($translationsContent, 0, $lineStart); + $lineEnd = $lineStart + strlen($match[0][0]); + $afterLine = substr($translationsContent, $lineEnd); + + $updatedContent = $beforeLine . $newLine . $afterLine; + + // Rebuild the full content + $newContent = substr($content, 0, $exportStart) + . $updatedContent + . substr($content, $closingBracePos); + + File::put($filePath, $newContent); + $this->info(" ✓ {$fileName} (updated)"); + } + } +} diff --git a/src/app/Console/Commands/DeleteTranslationKey.php b/src/app/Console/Commands/DeleteTranslationKey.php new file mode 100644 index 000000000..0ef4d1de7 --- /dev/null +++ b/src/app/Console/Commands/DeleteTranslationKey.php @@ -0,0 +1,152 @@ +argument('key'); + + $langPath = resource_path('js/lang'); + $files = File::glob($langPath . '/*.ts'); + + $files = array_filter($files, fn($file) => basename($file) !== 'index.ts'); + + if (empty($files)) { + $this->error("No translation files found in {$langPath}"); + return 1; + } + + $this->info("Deleting translation key '{$key}' from all language files..."); + + $deletedCount = 0; + $notFoundCount = 0; + + foreach ($files as $file) { + $result = $this->deleteKeyFromFile($file, $key); + if ($result) { + $deletedCount++; + } else { + $notFoundCount++; + } + } + + if ($deletedCount > 0) { + $this->info("\n✓ Translation key '{$key}' deleted from {$deletedCount} file(s)."); + } + + if ($notFoundCount > 0) { + $this->warn("Key not found in {$notFoundCount} file(s)."); + } + + return 0; + } + + private function deleteKeyFromFile(string $filePath, string $key): bool + { + $fileName = basename($filePath); + $content = File::get($filePath); + + // Find the translations export (e.g., export const enTranslations = {) + if (!preg_match('/export const \w+Translations = \{/', $content, $matches, PREG_OFFSET_CAPTURE)) { + $this->error("Could not find translations export in {$fileName}"); + return false; + } + + $exportStart = $matches[0][1] + strlen($matches[0][0]); + + $closingBracePos = $this->findClosingBrace($content, $exportStart); + + if ($closingBracePos === false) { + $this->error("Could not find closing brace for translations in {$fileName}"); + return false; + } + + // Extract the translations section + $translationsContent = substr($content, $exportStart, $closingBracePos - $exportStart); + + // Find the line with the key + $pattern = '/^(\s*)' . preg_quote($key, '/') . ':.*?(?:,\s*(?:\/\/.*)?)?$/m'; + if (!preg_match($pattern, $translationsContent, $match, PREG_OFFSET_CAPTURE)) { + $this->warn(" {$fileName}: Key '{$key}' not found"); + return false; + } + + $lineStart = $match[0][1]; + $lineLength = strlen($match[0][0]); + + // Remove the line including the newline + $beforeLine = substr($translationsContent, 0, $lineStart); + $afterLine = substr($translationsContent, $lineStart + $lineLength); + + // Remove the newline after the key + if (substr($afterLine, 0, 1) === "\n") { + $afterLine = substr($afterLine, 1); + } + + // Check if we need to fix comma on the previous line + // If the deleted line had no comma and the previous line exists, + // and the next content is not the closing brace, we may need to add a comma + $hasComma = preg_match('/,\s*(?:\/\/.*)?$/', $match[0][0]); + + if (!$hasComma && trim($afterLine) !== '' && !preg_match('/^\s*}/', $afterLine)) { + // The deleted line didn't have a comma, but there's more content after + // We need to ensure the previous line has a comma + if (preg_match('/^(.*?)(\s*(?:\/\/.*)?)\s*$/s', rtrim($beforeLine, "\n"), $prevMatch)) { + $beforeContent = $prevMatch[1]; + $trailingComment = $prevMatch[2] ?? ''; + + // Check if the last line already has a comma + if (!preg_match('/,\s*$/', $beforeContent)) { + // Add comma before any trailing comment + $beforeLine = rtrim($beforeContent, " \t") . ',' . $trailingComment . "\n"; + } + } + } + + $updatedContent = $beforeLine . $afterLine; + + // Rebuild the full content + $newContent = substr($content, 0, $exportStart) + . $updatedContent + . substr($content, $closingBracePos); + + File::put($filePath, $newContent); + $this->info(" ✓ {$fileName}"); + + return true; + } + + private function findClosingBrace(string $content, int $startPos): int|false + { + $depth = 1; + $length = strlen($content); + + for ($i = $startPos; $i < $length; $i++) { + if ($content[$i] === '{') { + $depth++; + } elseif ($content[$i] === '}') { + $depth--; + if ($depth === 0) { + return $i; + } + } + } + + return false; + } +} diff --git a/src/app/Console/Commands/ImportRootServers.php b/src/app/Console/Commands/ImportRootServers.php index 322a994b1..5ea4b3889 100644 --- a/src/app/Console/Commands/ImportRootServers.php +++ b/src/app/Console/Commands/ImportRootServers.php @@ -19,6 +19,9 @@ use App\Repositories\External\ExternalRootServer; use App\Repositories\External\ExternalServiceBody; use App\Repositories\External\InvalidObjectException; +use App\Repositories\Import\FormatImportResult; +use App\Repositories\Import\MeetingImportResult; +use App\Repositories\Import\ServiceBodyImportResult; use Carbon\Carbon; use Illuminate\Console\Command; use Illuminate\Database\Query\Builder; @@ -27,7 +30,7 @@ class ImportRootServers extends Command { - protected $signature = 'aggregator:ImportRootServers {--list-url=https://raw.githubusercontent.com/bmlt-enabled/aggregator/main/rootServerList.json}'; + protected $signature = 'aggregator:ImportRootServers {--list-url=https://raw.githubusercontent.com/bmlt-enabled/aggregator/main/serverList.json}'; protected $description = 'Import root servers'; @@ -42,7 +45,7 @@ public function handle( MeetingRepositoryInterface $meetingRepository, ServiceBodyRepositoryInterface $serviceBodyRepository ) { - if (!legacy_config('aggregator_mode_enabled')) { + if (!file_config('aggregator_mode_enabled')) { $this->error('aggregator mode is not enabled'); return; } @@ -84,21 +87,16 @@ private function importRootServersList(RootServerRepositoryInterface $rootServer { try { $url = $this->option('list-url'); - $response = $this->httpGet($url); - $externalRootServers = collect($response) - ->map(function ($rootServer) { - try { - return new ExternalRootServer($rootServer); - } catch (InvalidObjectException) { - return null; - } - }) - ->reject(fn($e) => is_null($e)); - $rootServerRepository->import($externalRootServers); + $response = $this->httpGet($url, true); + $externalRootServers = collect($response)->map(fn ($rs) => new ExternalRootServer($rs)); + $result = $rootServerRepository->import($externalRootServers); } catch (\Exception $e) { $this->error($e->getMessage()); throw $e; } + $this->info("created $result->numCreated"); + $this->info("updated $result->numUpdated"); + $this->info("deleted $result->numDeleted"); } private function importRootServer( @@ -110,9 +108,24 @@ private function importRootServer( ): void { $this->info("importing root server $rootServer->id:$rootServer->url"); $this->importServerInfo($rootServer, $rootServerRepository); - $this->importServiceBodies($rootServer, $serviceBodyRepository); - $this->importFormats($rootServer, $formatRepository); - $this->importMeetings($rootServer, $meetingRepository); + + $serviceBodiesResult = $this->importServiceBodies($rootServer, $serviceBodyRepository); + $this->info(" created $serviceBodiesResult->numCreated"); + $this->info(" updated $serviceBodiesResult->numUpdated"); + $this->info(" reassigned $serviceBodiesResult->numReassigned"); + $this->info(" deleted $serviceBodiesResult->numDeleted"); + + $formatsResult = $this->importFormats($rootServer, $formatRepository); + $this->info(" created $formatsResult->numCreated"); + $this->info(" updated $formatsResult->numUpdated"); + $this->info(" deleted $formatsResult->numDeleted"); + + $meetingsResult = $this->importMeetings($rootServer, $meetingRepository); + $this->info(" created $meetingsResult->numCreated"); + $this->info(" updated $meetingsResult->numUpdated"); + $this->info(" deleted $meetingsResult->numDeleted"); + $this->info(" orphaned and deleted $meetingsResult->numOrphaned"); + $this->updateStatistics($rootServer); $rootServerRepository->update($rootServer->id, ['last_successful_import' => Carbon::now()]); } @@ -126,7 +139,7 @@ private function importServerInfo(RootServer $rootServer, RootServerRepositoryIn $rootServer->refresh(); } - private function importServiceBodies(RootServer $rootServer, ServiceBodyRepositoryInterface $serviceBodyRepository) + private function importServiceBodies(RootServer $rootServer, ServiceBodyRepositoryInterface $serviceBodyRepository): ServiceBodyImportResult { $this->info('importing service bodies'); $url = rtrim($rootServer->url, '/') . '/client_interface/json/?switcher=GetServiceBodies'; @@ -141,10 +154,10 @@ private function importServiceBodies(RootServer $rootServer, ServiceBodyReposito } }) ->reject(fn($e) => is_null($e)); - $serviceBodyRepository->import($rootServer->id, $externalServiceBodies); + return $serviceBodyRepository->import($rootServer->id, $externalServiceBodies); } - private function importFormats(RootServer $rootServer, FormatRepositoryInterface $formatRepository) + private function importFormats(RootServer $rootServer, FormatRepositoryInterface $formatRepository): FormatImportResult { $this->info('importing formats'); $serverInfo = json_decode($rootServer->server_info); @@ -153,7 +166,7 @@ private function importFormats(RootServer $rootServer, FormatRepositoryInterface $url = rtrim($rootServer->url, '/') . '/client_interface/json/?switcher=GetFormats'; $externalFormats = collect([]); foreach ($languages as $language) { - $this->info("importing formats:$language"); + $this->info(" retrieving $language"); $response = $this->httpGet($url . "&lang_enum=$language"); $externalFormats = $externalFormats->concat( collect($response) @@ -170,10 +183,10 @@ private function importFormats(RootServer $rootServer, FormatRepositoryInterface ); } - $formatRepository->import($rootServer->id, $externalFormats); + return $formatRepository->import($rootServer->id, $externalFormats); } - private function importMeetings(RootServer $rootServer, MeetingRepositoryInterface $meetingRepository) + private function importMeetings(RootServer $rootServer, MeetingRepositoryInterface $meetingRepository): MeetingImportResult { $this->info('importing meetings'); $url = rtrim($rootServer->url, '/') . '/client_interface/json/?switcher=GetSearchResults'; @@ -188,7 +201,7 @@ private function importMeetings(RootServer $rootServer, MeetingRepositoryInterfa } }) ->reject(fn($e) => is_null($e)); - $meetingRepository->import($rootServer->id, $externalMeetings); + return $meetingRepository->import($rootServer->id, $externalMeetings); } private function updateStatistics(RootServer $rootServer) @@ -227,7 +240,7 @@ private function getNumGroups(RootServer $rootServer): int ->whereIn('meetingid_bigint', function ($query) use ($serviceBody) { $query ->select('id_bigint') - ->from((new Meeting)->getTable()) + ->from((new Meeting())->getTable()) ->where('service_body_bigint', $serviceBody->id_bigint) ->where(function (Builder $query) { $query @@ -247,13 +260,13 @@ private function analyzeTables(): void $this->info('analyzing tables'); $prefix = DB::connection()->getTablePrefix(); $tableNames = [ - $prefix . (new Meeting)->getTable(), - $prefix . (new MeetingData)->getTable(), - $prefix . (new MeetingLongData)->getTable(), - $prefix . (new ServiceBody)->getTable(), - $prefix . (new Format)->getTable(), - $prefix . (new RootServer)->getTable(), - $prefix . (new RootServerStatistics)->getTable(), + $prefix . (new Meeting())->getTable(), + $prefix . (new MeetingData())->getTable(), + $prefix . (new MeetingLongData())->getTable(), + $prefix . (new ServiceBody())->getTable(), + $prefix . (new Format())->getTable(), + $prefix . (new RootServer())->getTable(), + $prefix . (new RootServerStatistics())->getTable(), ]; foreach ($tableNames as $tableName) { $sql = DB::raw("ANALYZE TABLE $tableName;")->getValue(DB::connection()->getQueryGrammar()); @@ -261,13 +274,17 @@ private function analyzeTables(): void } } - private function httpGet(string $url): array + private function httpGet(string $url, bool $shouldLogResponse = false): array { sleep(self::$requestDelaySeconds); - $headers = ['User-Agent' => 'Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0 +aggregator']; + $headers = ['User-Agent' => file_config('aggregator_user_agent')]; $response = Http::withHeaders($headers)->retry(3, self::$retryDelaySeconds * 1000)->get($url); + if ($shouldLogResponse) { + $this->info("response from $url: $response"); + } + if (!$response->ok()) { throw new \Exception("Got bad status code {$response->status()} from $url"); } diff --git a/src/app/Console/Commands/InitializeDatabase.php b/src/app/Console/Commands/InitializeDatabase.php index c53d01e08..1109e7908 100644 --- a/src/app/Console/Commands/InitializeDatabase.php +++ b/src/app/Console/Commands/InitializeDatabase.php @@ -14,7 +14,7 @@ class InitializeDatabase extends Command public function handle() { - if (!legacy_config('aggregator_mode_enabled')) { + if (!file_config('aggregator_mode_enabled')) { $this->error('aggregator mode is not enabled'); return; } diff --git a/src/app/Console/Commands/PrimeDatabaseFromLegacyTomato.php b/src/app/Console/Commands/PrimeDatabaseFromLegacyTomato.php index 338ffcd68..4c61d7cdf 100644 --- a/src/app/Console/Commands/PrimeDatabaseFromLegacyTomato.php +++ b/src/app/Console/Commands/PrimeDatabaseFromLegacyTomato.php @@ -26,7 +26,7 @@ class PrimeDatabaseFromLegacyTomato extends Command public function handle(RootServerRepository $rootServerRepository) { - if (!legacy_config('aggregator_mode_enabled')) { + if (!file_config('aggregator_mode_enabled')) { $this->error('aggregator mode is not enabled'); return; } @@ -68,7 +68,7 @@ private function importRootServers(RootServerRepositoryInterface $rootServerRepo ->map(fn ($o) => [ 'id' => $o['source_id'], 'name' => $o['name'], - 'rootURL' => rtrim($o['root_server_url']) . '/', + 'url' => rtrim($o['root_server_url']) . '/', ]) ->map(function ($rootServer) { try { @@ -172,11 +172,11 @@ private function analyzeTables(): void $this->info('analyzing tables'); $prefix = DB::connection()->getTablePrefix(); $tableNames = [ - $prefix . (new Meeting)->getTable(), - $prefix . (new MeetingData)->getTable(), - $prefix . (new MeetingLongData)->getTable(), - $prefix . (new ServiceBody)->getTable(), - $prefix . (new Format)->getTable(), + $prefix . (new Meeting())->getTable(), + $prefix . (new MeetingData())->getTable(), + $prefix . (new MeetingLongData())->getTable(), + $prefix . (new ServiceBody())->getTable(), + $prefix . (new Format())->getTable(), ]; foreach ($tableNames as $tableName) { DB::statement("ANALYZE TABLE $tableName;"); diff --git a/src/app/Console/Commands/UpdateTranslationsFromSpreadsheet.php b/src/app/Console/Commands/UpdateTranslationsFromSpreadsheet.php new file mode 100644 index 000000000..d2c2b2ab4 --- /dev/null +++ b/src/app/Console/Commands/UpdateTranslationsFromSpreadsheet.php @@ -0,0 +1,160 @@ +argument('spreadsheet'); + $languageCode = $this->argument('language'); + + if ($languageCode === 'en') { + $this->error("Cannot update English translations from spreadsheet."); + $this->info("English translations should be updated directly in the source file or using 'translation:add' command."); + return 1; + } + + if (!file_exists($spreadsheetPath)) { + $this->error("Spreadsheet file not found: {$spreadsheetPath}"); + return 1; + } + + $langPath = resource_path("js/lang/{$languageCode}.ts"); + if (!File::exists($langPath)) { + $this->error("Translation file not found: {$langPath}"); + $this->info("Available languages: " . implode(', ', $this->getAvailableLanguages())); + return 1; + } + + try { + $this->info("Reading spreadsheet: {$spreadsheetPath}"); + $translations = $this->parseSpreadsheet($spreadsheetPath); + + if (empty($translations)) { + $this->error("No translations found in spreadsheet"); + return 1; + } + + $this->info("Found " . count($translations) . " translations in spreadsheet"); + + $backupFile = "{$langPath}.backup." . time(); + File::copy($langPath, $backupFile); + $this->info("Created backup: {$backupFile}"); + + $this->info("Updating {$languageCode}.ts..."); + $result = $this->updateTranslationFile($langPath, $translations); + + $this->info("\n📊 Translation summary:"); + $this->info(" • Keys found in spreadsheet: " . count($translations)); + $this->info(" • Updated existing keys: {$result['updated']}"); + $this->info(" • Keys not found in file: {$result['notFound']}"); + + if ($result['notFound'] > 0) { + $this->warn("\nKeys not found in {$languageCode}.ts:"); + foreach ($result['notFoundKeys'] as $key) { + $this->warn(" • {$key}"); + } + $this->warn("\nUse 'translation:add' command to add new keys first"); + } + + $this->info("\n✅ Translation file updated successfully!"); + $this->info("📁 Backup created at: {$backupFile}"); + + return 0; + } catch (\Exception $e) { + $this->error("Error: " . $e->getMessage()); + return 1; + } + } + + private function parseSpreadsheet(string $filePath): array + { + $spreadsheet = IOFactory::load($filePath); + $sheet = $spreadsheet->getActiveSheet(); + $highestRow = $sheet->getHighestRow(); + + $translations = []; + + // Start from row 2 (skip header: Key, English, Target Language) + for ($row = 2; $row <= $highestRow; $row++) { + $key = trim((string) $sheet->getCell("A{$row}")->getValue()); + // Column C contains the target language translation + $value = trim((string) $sheet->getCell("C{$row}")->getValue()); + + if ($key && $value) { + $translations[$key] = $value; + } + } + + return $translations; + } + + private function updateTranslationFile(string $filePath, array $newTranslations): array + { + $content = File::get($filePath); + $updated = 0; + $notFound = 0; + $notFoundKeys = []; + + foreach ($newTranslations as $key => $newValue) { + // Escape the new value for single quotes + $escapedValue = str_replace(['\\', "'"], ['\\\\', "\\'"], $newValue); + + // Match the key with its current value (both single and double quotes) + $pattern = '/^(\s*)' . preg_quote($key, '/') . ':\s*([\'"])(.*)\\2(,?)(.*?)$/m'; + + if (preg_match($pattern, $content, $match)) { + $indent = $match[1]; + $comma = $match[4]; + $restOfLine = $match[5]; // This captures comments like // TODO: translate + + // Build the replacement line with single quotes + $replacement = "{$indent}{$key}: '{$escapedValue}'{$comma}{$restOfLine}"; + + $content = preg_replace($pattern, $replacement, $content, 1); + $updated++; + } else { + $notFound++; + $notFoundKeys[] = $key; + } + } + + File::put($filePath, $content); + + return [ + 'updated' => $updated, + 'notFound' => $notFound, + 'notFoundKeys' => $notFoundKeys, + ]; + } + + private function getAvailableLanguages(): array + { + $langPath = resource_path('js/lang'); + $files = File::glob($langPath . '/*.ts'); + + return array_map(function ($file) { + $basename = basename($file, '.ts'); + return $basename !== 'index' ? $basename : null; + }, array_filter($files, fn($file) => basename($file) !== 'index.ts')); + } +} diff --git a/src/app/Console/Kernel.php b/src/app/Console/Kernel.php index e06a58fc9..30b73104c 100644 --- a/src/app/Console/Kernel.php +++ b/src/app/Console/Kernel.php @@ -29,7 +29,7 @@ protected function schedule(Schedule $schedule) */ protected function commands() { - $this->load(__DIR__.'/Commands'); + $this->load(__DIR__ . '/Commands'); // require base_path('routes/console.php'); } diff --git a/src/app/FromDatabaseConfig.php b/src/app/FromDatabaseConfig.php new file mode 100644 index 000000000..02328a91c --- /dev/null +++ b/src/app/FromDatabaseConfig.php @@ -0,0 +1,66 @@ +get($name); + } + + public static function get(string $name = null, $default = null) + { + if (!static::$configLoaded) { + static::loadConfig(); + } + + if (is_null($name)) { + return static::$config; + } + + return static::$config[$name] ?? $default; + } + + public static function set(string $name, $value) + { + // should only be used in testing + $repository = app(SettingRepository::class); + $repository->update($name, $value); + $setting = $repository->getByName($name); + static::$config[$name] = $setting->value; + } + + public static function reset(): void + { + // should only be used in testing + static::$config = null; + static::$settingTypes = null; + static::$configLoaded = false; + } + + private static function loadConfig(): void + { + static::$configLoaded = true; // we set this first thing to prevent infinite looping when calling into fromEnv + $repository = app(SettingRepository::class); + $settings = $repository->getAll(); + static::$settingTypes = $settings->mapWithKeys(fn ($s) => [$s->name => $s->type]); + static::$config = $settings + ->mapWithKeys(function ($setting) { + $value = static::fromEnv($setting->name) ?? $setting->value; + return [$setting->name => $value]; + }) + ->toArray(); + } +} diff --git a/src/app/FromFileConfig.php b/src/app/FromFileConfig.php new file mode 100644 index 000000000..13fbe1791 --- /dev/null +++ b/src/app/FromFileConfig.php @@ -0,0 +1,82 @@ + Setting::TYPE_STRING, + 'db_username' => Setting::TYPE_STRING, + 'db_password' => Setting::TYPE_STRING, + 'db_host' => Setting::TYPE_STRING, + 'db_prefix' => Setting::TYPE_STRING, + 'aggregator_mode_enabled' => Setting::TYPE_BOOL, + 'aggregator_max_geo_width_km' => Setting::TYPE_FLOAT, + 'aggregator_user_agent' => Setting::TYPE_STRING, + ]; + return $types[$name]; + } + + public static function get(?string $name = null, $default = null) + { + if (!static::$configLoaded) { + self::loadConfig(); + } + + if (is_null(static::$config)) { + return null; + } + + if (is_null($name)) { + return static::$config; + } + + return static::$config[$name] ?? $default; + } + + public static function set(string $name, $value) + { + // should only be used in testing + if (!static::$configLoaded) { + static::loadConfig(); + } + + static::$config[$name] = $value; + } + + public static function reset(): void + { + // should only be used in testing + static::$config = null; + static::$configLoaded = false; + } + + private static function loadConfig(): void + { + $configFile = base_path() . '/../auto-config.inc.php'; + if (file_exists($configFile)) { + defined('BMLT_EXEC') or define('BMLT_EXEC', 1); + require($configFile); + } + + static::$config = [ + 'db_database' => static::fromEnv('db_database') ?? $dbName ?? null, + 'db_username' => static::fromEnv('db_username') ?? $dbUser ?? null, + 'db_password' => static::fromEnv('db_password') ?? $dbPassword ?? null, + 'db_host' => static::fromEnv('db_host') ?? $dbServer ?? null, + 'db_prefix' => static::fromEnv('db_prefix') ?? $dbPrefix ?? null, + 'aggregator_mode_enabled' => static::fromEnv('aggregator_mode_enabled') ?? $aggregator_mode_enabled ?? false, + 'aggregator_max_geo_width_km' => static::fromEnv('aggregator_max_geo_width_km') ?? $aggregator_max_geo_width_km ?? null, + 'aggregator_user_agent' => static::fromEnv('aggregator_user_agent') ?? $aggregator_user_agent ?? 'Mozilla/5.0 (X11; Linux x86_64; rv:146.0) Gecko/20100101 Firefox/146.0 +aggregator', + ]; + + static::$configLoaded = true; + } +} diff --git a/src/app/Http/Controllers/Admin/FormatController.php b/src/app/Http/Controllers/Admin/FormatController.php index 224276e80..24f9f9869 100644 --- a/src/app/Http/Controllers/Admin/FormatController.php +++ b/src/app/Http/Controllers/Admin/FormatController.php @@ -7,6 +7,8 @@ use App\Interfaces\FormatRepositoryInterface; use App\Models\Format; use App\Models\FormatType; +use App\Rules\FormatTranslationKey; +use App\Rules\FormatTranslations; use Illuminate\Http\Request; use Illuminate\Support\Collection; use Illuminate\Validation\Rule; @@ -21,20 +23,17 @@ public function __construct(FormatRepositoryInterface $formatRepository) $this->authorizeResource(Format::class); } - public function index(Request $request) { $formats = $this->formatRepository->getAsTranslations(); return FormatResource::collection($formats); } - public function show(Format $format) { return new FormatResource($format); } - public function store(Request $request) { $validated = $this->validateInputs($request); @@ -45,7 +44,7 @@ public function store(Request $request) public function update(Request $request, Format $format) { - $validated = $this->validateInputs($request); + $validated = $this->validateInputs($request, $format->shared_id_bigint); $sharedFormatsValues = $this->buildValuesArray($validated); $this->formatRepository->update($format->shared_id_bigint, $sharedFormatsValues); return response()->noContent(); @@ -59,7 +58,7 @@ public function partialUpdate(Request $request, Format $format) if ($fieldName == 'worldId') { return [$fieldName => $request->has($fieldName) ? $request->input($fieldName) : $format->worldid_mixed]; } elseif ($fieldName == 'type') { - return [$fieldName => $request->has($fieldName) ? $request->input($fieldName) : (!is_null($format->format_type_enum) ? FormatType::getApiEnumFromKey($format->format_type_enum): null)]; + return [$fieldName => $request->has($fieldName) ? $request->input($fieldName) : (!is_null($format->format_type_enum) ? FormatType::getApiEnumFromKey($format->format_type_enum) : null)]; } else { return [$fieldName => $request->has($fieldName) ? $request->input($fieldName) : $format->translations->map(function ($translation) { return [ @@ -74,13 +73,12 @@ public function partialUpdate(Request $request, Format $format) ->toArray() ); - $validated = $this->validateInputs($request); + $validated = $this->validateInputs($request, $format->shared_id_bigint); $sharedFormatsValues = $this->buildValuesArray($validated); $this->formatRepository->update($format->shared_id_bigint, $sharedFormatsValues); return response()->noContent(); } - public function destroy(Request $request, Format $format) { $request->merge(['id' => $format->shared_id_bigint]); @@ -100,7 +98,7 @@ public function destroy(Request $request, Format $format) return response()->noContent(); } - private function validateInputs(Request $request) + private function validateInputs(Request $request, int $formatId = null): Collection { return collect($request->validate([ 'worldId' => 'nullable|string|max:30', @@ -114,9 +112,10 @@ function ($attribute, $value, $fail) { $fail(':attribute may have only one translation per language.'); } } - } + }, + new FormatTranslations($this->formatRepository, $formatId) ], - 'translations.*.key' => ['required', 'string', 'max:10', Rule::notIn(['VM', 'HY', 'TC'])], + 'translations.*.key' => ['required', 'string', 'max:10', new FormatTranslationKey($this->formatRepository, $formatId)], 'translations.*.name' => 'required|string|max:255', 'translations.*.description' => 'required|string|max:255', 'translations.*.language' => 'required|string|max:7', diff --git a/src/app/Http/Controllers/Admin/MeetingController.php b/src/app/Http/Controllers/Admin/MeetingController.php index abbfaf273..e09c9c0bf 100644 --- a/src/app/Http/Controllers/Admin/MeetingController.php +++ b/src/app/Http/Controllers/Admin/MeetingController.php @@ -59,12 +59,20 @@ public function index(Request $request) return MeetingResource::collection($meetings); } - + public function searchTranslations(Request $request) + { + $this->meetingRepository->setTargetLanguage($request->lang); + return $this->index($request); + } public function show(Meeting $meeting) { return new MeetingResource($meeting); } - + public function getTranslation(Request $request, Meeting $meeting) + { + $this->meetingRepository->setTargetLanguage($request->lang); + return new MeetingResource($meeting); + } public function store(Request $request) { $validated = $this->validateInputs($request); @@ -80,7 +88,23 @@ public function update(Request $request, Meeting $meeting) $this->meetingRepository->update($meeting->id_bigint, $values); return response()->noContent(); } - + public function translate(Request $request, Meeting $meeting) + { + $this->meetingRepository->setTargetLanguage($request->lang); + $validated = $this->validateTranslationInputs($request); + if (isset($validated['customFields'])) { + foreach ($validated['customFields'] as $key => $value) { + $validated[$key] = $value; + } + unset($validated['customFields']); + } + if (isset($validated['name'])) { + $validated['meeting_name'] = $validated['name']; + unset($validated['name']); + } + $this->meetingRepository->translate($meeting->id_bigint, $validated); + return response()->noContent(); + } public function partialUpdate(Request $request, Meeting $meeting) { $meetingData = $meeting->data @@ -169,7 +193,12 @@ private function getCustomFields(): Collection } return $customFields; } - + private function validateTranslationInputs(Request $request) + { + return $request->validate( + array_merge(['name' => 'nullable|string|max:128'], $this->getDataFieldValidators(true)) + ); + } private function validateInputs(Request $request, $skipVenueTypeLocationValidation = false) { return collect($request->validate( @@ -188,7 +217,7 @@ private function validateInputs(Request $request, $skipVenueTypeLocationValidati 'email' => 'nullable|email|max:255', 'worldId' => 'nullable|string|max:30', 'name' => 'required|string|max:128', - 'timeZone' => ['nullable', 'string', 'max:40', new IANATimeZone], + 'timeZone' => ['nullable', 'string', 'max:40', new IANATimeZone()], ], $this->getDataFieldValidators($skipVenueTypeLocationValidation)) )); } @@ -200,7 +229,7 @@ private function getDataFieldValidators($skipVenueTypeLocationValidation = false ->reject(fn ($_, $fieldName) => $fieldName == 'meeting_name' || $customFields->contains($fieldName)) ->mapWithKeys(function ($_, $fieldName) use ($skipVenueTypeLocationValidation) { if (!$skipVenueTypeLocationValidation && in_array($fieldName, VenueTypeLocation::FIELDS)) { - return [$fieldName => ['max:512', new VenueTypeLocation]]; + return [$fieldName => ['max:512', new VenueTypeLocation()]]; } else { return [$fieldName => 'nullable|string|max:512']; } diff --git a/src/app/Http/Controllers/Admin/RootServerController.php b/src/app/Http/Controllers/Admin/RootServerController.php index 2084dccbe..a804a8048 100644 --- a/src/app/Http/Controllers/Admin/RootServerController.php +++ b/src/app/Http/Controllers/Admin/RootServerController.php @@ -19,7 +19,7 @@ public function __construct(RootServerRepositoryInterface $rootServerRepository) public function index(Request $request) { - if (!legacy_config('aggregator_mode_enabled')) { + if (!file_config('aggregator_mode_enabled')) { return new JsonResponse(['message' => 'Endpoint is unavailable when aggregator mode is disabled.'], 404); } @@ -29,7 +29,7 @@ public function index(Request $request) public function show(RootServer $rootServer) { - if (!legacy_config('aggregator_mode_enabled')) { + if (!file_config('aggregator_mode_enabled')) { return new JsonResponse(['message' => 'Endpoint is unavailable when aggregator mode is disabled.'], 404); } diff --git a/src/app/Http/Controllers/Admin/SettingController.php b/src/app/Http/Controllers/Admin/SettingController.php new file mode 100644 index 000000000..f9552662b --- /dev/null +++ b/src/app/Http/Controllers/Admin/SettingController.php @@ -0,0 +1,52 @@ +settingRepository = $settingRepository; + } + + public function index(Request $request) + { + $this->authorize('viewAny', Setting::class); + + $settings = $this->settingRepository->getAll()->map(function ($setting) { + $setting->value = FromDatabaseConfig::fromEnv($setting->name) ?? $setting->value; + return $setting; + }); + return response()->json(SettingResource::collection($settings)); + } + + public function update(Request $request) + { + $this->authorize('update', Setting::class); + $settingTypes = $this->settingRepository->getAll()->mapWithKeys(fn ($s) => [$s->name => $s->type]); + $rules = array_merge( + ['*' => Rule::in($settingTypes->keys())], + $settingTypes->mapWithKeys(function ($type, $name) { + return [$name => match ($type) { + Setting::TYPE_STRING => 'nullable|string|max:65535', + Setting::TYPE_INT => 'nullable|integer', + Setting::TYPE_FLOAT => 'nullable|numeric', + Setting::TYPE_BOOL => 'nullable|boolean', + Setting::TYPE_ARRAY => 'nullable|array', + }]; + })->toArray() + ); + $validated = $request->validate($rules); + $this->settingRepository->updateMultiple($validated); + return response()->noContent(); + } +} diff --git a/src/app/Http/Controllers/Admin/Swagger/FormatController.php b/src/app/Http/Controllers/Admin/Swagger/FormatController.php index a1479cb00..ae0857fe1 100644 --- a/src/app/Http/Controllers/Admin/Swagger/FormatController.php +++ b/src/app/Http/Controllers/Admin/Swagger/FormatController.php @@ -35,7 +35,6 @@ */ class FormatController extends Controller { - /** * @OA\Get(path="/api/v1/formats", summary="Retrieves formats", description="Retrieve formats", operationId="getFormats", tags={"rootServer"}, security={{"bmltToken":{}}}, * @OA\Response(response=200, description="Returns when user is authenticated.", diff --git a/src/app/Http/Controllers/Admin/Swagger/MeetingController.php b/src/app/Http/Controllers/Admin/Swagger/MeetingController.php index 73b7ecd09..86f2726e8 100644 --- a/src/app/Http/Controllers/Admin/Swagger/MeetingController.php +++ b/src/app/Http/Controllers/Admin/Swagger/MeetingController.php @@ -67,7 +67,6 @@ class MeetingController extends Controller { - /** * @OA\Get(path="/api/v1/meetings", summary="Retrieves meetings", description="Retrieve meetings for authenticated user.", operationId="getMeetings", tags={"rootServer"}, security={{"bmltToken":{}}}, * @OA\Parameter(description="comma delimited meeting ids", in="query", name="meetingIds", required=false, example="1,2", @@ -96,7 +95,37 @@ class MeetingController extends Controller public function index() { } - + /** + * @OA\Get(path="/api/v1/translations/meetings/{lang}", summary="Retrieves meetings with translated values", description="Retrieve meetings for authenticated user.", operationId="getTranslatedMeetings", tags={"rootServer"}, security={{"bmltToken":{}}}, + * @OA\Parameter(description="language", in="path", name="lang", required=true, example="en", + * @OA\Schema(type="string") + * ), + * @OA\Parameter(description="comma delimited meeting ids", in="query", name="meetingIds", required=false, example="1,2", + * @OA\Schema(type="string") + * ), + * @OA\Parameter(description="comma delimited day ids between 0-6", in="query", name="days", required=false, example="0,1", + * @OA\Schema(type="string") + * ), + * @OA\Parameter(description="comma delimited service body ids", in="query", name="serviceBodyIds", required=false, example="3,4", + * @OA\Schema(type="string") + * ), + * @OA\Parameter(description="string", in="query", name="searchString", required=false, example="Just for Today", + * @OA\Schema(type="string") + * ), + * @OA\Response(response=200, description="List of meetings.", + * @OA\JsonContent(ref="#/components/schemas/MeetingCollection") + * ), + * @OA\Response(response=401, description="Returns when user is not authenticated.", + * @OA\JsonContent(ref="#/components/schemas/AuthenticationError") + * ), + * @OA\Response(response=422, description="Validation error.", + * @OA\JsonContent(ref="#/components/schemas/ValidationError") + * ), + * ) + */ + public function translateIndex() + { + } /** * @OA\Get(path="/api/v1/meetings/{meetingId}", summary="Retrieves a meeting", description="Retrieve a meeting.", operationId="getMeeting", tags={"rootServer"}, security={{"bmltToken":{}}}, * @OA\Parameter(description="ID of meeting", in="path", name="meetingId", required=true, example="1", @@ -116,7 +145,28 @@ public function index() public function show() { } - + /** + * @OA\Get(path="/api/v1/translations/meetings/{meetingId}/{lang}", summary="Retrieves a meeting translation", description="Retrieve a meeting.", operationId="getMeetingTranslation", tags={"rootServer"}, security={{"bmltToken":{}}}, + * @OA\Parameter(description="language", in="path", name="lang", required=true, example="en", + * @OA\Schema(type="string") + * ), + * @OA\Parameter(description="ID of meeting", in="path", name="meetingId", required=true, example="1", + * @OA\Schema(type="integer",format="int64") + * ), + * @OA\Response(response=200, description="Returns when user is authenticated.", + * @OA\JsonContent(ref="#/components/schemas/Meeting") + * ), + * @OA\Response(response=401, description="Returns when user is not authenticated.", + * @OA\JsonContent(ref="#/components/schemas/AuthenticationError") + * ), + * @OA\Response(response=404, description="Returns when no meeting exists.", + * @OA\JsonContent(ref="#/components/schemas/NotFoundError") + * ), + * ) + */ + public function showTranslation() + { + } /** * @OA\Post(path="/api/v1/meetings", summary="Creates a meeting", description="Creates a meeting.", operationId="createMeeting", tags={"rootServer"}, security={{"bmltToken":{}}}, * @OA\RequestBody(required=true, description="Pass in meeting object", @@ -199,6 +249,34 @@ public function update() public function partialUpdate() { } + /** @OA\Patch(path="/api/v1/translations/meetings/{meetingId}/{lang}", summary="Translates the a meeting data", description="Provide tranlations for a meeting by id", operationId="translateMeeting", tags={"rootServer"}, security={{"bmltToken":{}}}, + * @OA\Parameter(description="language", in="path", name="lang", required=true, example="en", + * @OA\Schema(type="string") + * ), + * @OA\Parameter(description="ID of meeting", in="path", name="meetingId", required=true, example="1", + * @OA\Schema(type="integer", format="int64") + * ), + * @OA\RequestBody(required=true, description="Pass in fields you want to update.", + * @OA\JsonContent(ref="#/components/schemas/MeetingPartialUpdate"), + * ), + * @OA\Response(response=204, description="Success."), + * @OA\Response(response=401, description="Returns when user is not authenticated.", + * @OA\JsonContent(ref="#/components/schemas/AuthenticationError") + * ), + * @OA\Response(response=403, description="Returns when user is unauthorized to perform action.", + * @OA\JsonContent(ref="#/components/schemas/AuthorizationError") + * ), + * @OA\Response(response=404, description="Returns when no meeting exists.", + * @OA\JsonContent(ref="#/components/schemas/NotFoundError") + * ), + * @OA\Response(response=422, description="Validation error.", + * @OA\JsonContent(ref="#/components/schemas/ValidationError") + * ), + * ) + */ + public function translate() + { + } /** * @OA\Delete(path="/api/v1/meetings/{meetingId}", summary="Deletes a meeting", description="Deletes a meeting by id.", operationId="deleteMeeting", tags={"rootServer"}, security={{"bmltToken":{}}}, diff --git a/src/app/Http/Controllers/Admin/Swagger/RootServerController.php b/src/app/Http/Controllers/Admin/Swagger/RootServerController.php index d131d2859..e576899b2 100644 --- a/src/app/Http/Controllers/Admin/Swagger/RootServerController.php +++ b/src/app/Http/Controllers/Admin/Swagger/RootServerController.php @@ -35,7 +35,6 @@ */ class RootServerController extends Controller { - /** * @OA\Get(path="/api/v1/rootservers", summary="Retrieves root servers", description="Retrieve root servers.", operationId="getRootServers", tags={"rootServer"}, * @OA\Response(response=200, description="Successful response.", diff --git a/src/app/Http/Controllers/Admin/Swagger/ServiceBodyController.php b/src/app/Http/Controllers/Admin/Swagger/ServiceBodyController.php index 499ca709b..d19e44c02 100644 --- a/src/app/Http/Controllers/Admin/Swagger/ServiceBodyController.php +++ b/src/app/Http/Controllers/Admin/Swagger/ServiceBodyController.php @@ -36,7 +36,6 @@ */ class ServiceBodyController extends Controller { - /** * @OA\Get(path="/api/v1/servicebodies", summary="Retrieves service bodies", description="Retrieve service bodies for authenticated user.", operationId="getServiceBodies", tags={"rootServer"}, security={{"bmltToken":{}}}, * @OA\Response(response=200, description="Returns when user is authenticated.", diff --git a/src/app/Http/Controllers/Admin/Swagger/SettingController.php b/src/app/Http/Controllers/Admin/Swagger/SettingController.php new file mode 100644 index 000000000..426085429 --- /dev/null +++ b/src/app/Http/Controllers/Admin/Swagger/SettingController.php @@ -0,0 +1,99 @@ +url = rtrim(url('/'), '/') . '/'; $server->description = 'this server'; diff --git a/src/app/Http/Controllers/Admin/TokenController.php b/src/app/Http/Controllers/Admin/TokenController.php index d08eb77d0..b5db0064c 100644 --- a/src/app/Http/Controllers/Admin/TokenController.php +++ b/src/app/Http/Controllers/Admin/TokenController.php @@ -75,8 +75,13 @@ private function createToken(User $user) $expiresAt = 60 * config('sanctum.expiration', 0); $expiresAt += time(); + $token = $user->createToken(Str::random(20)); + + $user->last_access_datetime = $token->accessToken->created_at; + $user->save(); + return [ - 'access_token' => $user->createToken(Str::random(20))->plainTextToken, + 'access_token' => $token->plainTextToken, 'expires_at' => $expiresAt, 'token_type' => 'bearer', 'user_id' => $user->id_bigint, diff --git a/src/app/Http/Controllers/Admin/UserController.php b/src/app/Http/Controllers/Admin/UserController.php index 3cbebf14b..9fe684029 100644 --- a/src/app/Http/Controllers/Admin/UserController.php +++ b/src/app/Http/Controllers/Admin/UserController.php @@ -56,6 +56,7 @@ public function store(Request $request) 'displayName' => 'required|string|max:255', 'description' => 'nullable|string|max:1024', 'email' => 'nullable|email', + 'targetLanguage' => 'required_if:type,' . User::USER_TYPE_TRANSLATOR . '|string|max:10', 'ownerId' => 'nullable|present|int|exists:comdef_users,id_bigint', ]); @@ -72,6 +73,7 @@ public function store(Request $request) 'description_string' => $validated['description'] ?? '', 'email_address_string' => $validated['email'] ?? '', 'owner_id_bigint' => $validated['ownerId'] ?? -1, + 'target_language' => $validated['targetLanguage'] ?? '', ]); return new UserResource($user); } @@ -97,6 +99,8 @@ public function partialUpdate(Request $request, User $user) return ['displayName' => $request->has('displayName') ? $request->input('displayName') : $user->name_string]; } elseif ($fieldName == 'description_string') { return ['description' => $request->has('description') ? $request->input('description') : $user->description_string]; + } elseif ($fieldName == 'target_language') { + return ['description' => $request->has('targetLanguage') ? $request->input('targetLanguage') : $user->target_language]; } elseif ($fieldName == 'email_address_string') { return ['email' => $request->has('email') ? $request->input('email') : $user->email_address_string]; } elseif ($fieldName == 'password_string') { @@ -137,6 +141,7 @@ private function validateForUpdate(Request $request, User $user): Collection 'description' => 'nullable|string|max:1024', 'email' => 'nullable|email', 'ownerId' => 'nullable|present|int|exists:comdef_users,id_bigint', + 'targetLanguage' => 'required_if:type,' . User::USER_TYPE_TRANSLATOR . '|string|max:10', ])); $ownerId = $validated->get('ownerId'); @@ -174,6 +179,8 @@ private function buildValuesArrayForUpdate(Request $request, User $user, Collect return [$fieldName => $validated['description'] ?? '']; } elseif ($fieldName == 'email_address_string') { return [$fieldName => $validated['email'] ?? '']; + } elseif ($fieldName == 'target_language') { + return [$fieldName => $validated['targetLanguage'] ?? '']; } else { return [null => null]; } diff --git a/src/app/Http/Controllers/CatchAllController.php b/src/app/Http/Controllers/CatchAllController.php deleted file mode 100644 index 79e9f5c7c..000000000 --- a/src/app/Http/Controllers/CatchAllController.php +++ /dev/null @@ -1,116 +0,0 @@ -path)) { - return self::legacyResponse($pathInfo); - } - return response('"the aggregator formerly known as tomato"'); - } - - if (legacy_config('new_ui_enabled')) { - if (self::isAllowedLegacyPath($pathInfo) && file_exists($pathInfo->path)) { - return self::legacyResponse($pathInfo); - } - - return response()->view('frontend', [ - 'autoGeocodingEnabled' => legacy_config('auto_geocoding_enabled'), - 'baseUrl' => $request->getBaseurl(), - 'bmltTitle' => legacy_config('bmlt_title'), - 'bmltNotice' => legacy_config('bmlt_notice'), - 'centerLongitude' => legacy_config('search_spec_map_center_longitude'), - 'centerLatitude' => legacy_config('search_spec_map_center_latitude'), - 'centerZoom' => legacy_config('search_spec_map_center_zoom'), - 'countyAutoGeocodingEnabled' => legacy_config('county_auto_geocoding_enabled'), - 'customFields' => self::getCustomFields(), - 'defaultClosedStatus' => legacy_config('default_closed_status'), - 'defaultDuration' => legacy_config('default_duration_time'), - 'defaultLanguage' => legacy_config('language'), - 'distanceUnits' => legacy_config('distance_units'), - 'googleApiKey' => legacy_config('google_api_key', ''), - 'isLanguageSelectorEnabled' => legacy_config('enable_language_selector'), - 'languageMapping' => self::getLanguageMapping(), - 'meetingStatesAndProvinces' => implode(',', legacy_config('meeting_states_and_provinces', [])), - 'meetingCountiesAndSubProvinces' => implode(',', legacy_config('meeting_counties_and_sub_provinces', [])), - 'regionBias' => legacy_config('region_bias'), - 'version' => config('app.version'), - 'zipAutoGeocodingEnabled' => legacy_config('zip_auto_geocoding_enabled'), - ]); - } - - if (file_exists($pathInfo->path)) { - return self::legacyResponse($pathInfo); - } - - abort(404); - } - - private static function getLanguageMapping(): array - { - return collect(scandir(base_path('lang'))) - ->reject(fn ($dir) => str_starts_with($dir, '.')) - ->sort() - ->mapWithKeys(function ($langAbbreviation, $_) { - $langName = $langAbbreviation == 'dk' ? 'da' : $langAbbreviation; - $langName = \Locale::getDisplayLanguage($langName, $langName); - $langName = mb_str_split($langName); - $langName = mb_strtoupper($langName[0]) . implode('', array_slice($langName, 1)); - return [$langAbbreviation => $langName]; - }) - ->toArray(); - } - - private static function getCustomFields(): Collection - { - $meetingRepository = resolve(MeetingRepositoryInterface::class); - $customFields = $meetingRepository->getCustomFields(); - return $meetingRepository->getDataTemplates() - ->reject(fn ($t) => !$customFields->contains($t->key)) - ->map(fn ($t) => [ - 'name' => $t->key, - 'displayName' => $t->field_prompt, - 'language' => $t->lang_enum - ]) - ->values(); - } - - private static function isAllowedLegacyPath(LegacyPathInfo $pathInfo): bool - { - foreach (self::$allowedLegacyPathEndings as $allowedPathEnding) { - if (str_ends_with($pathInfo->path, $allowedPathEnding)) { - return true; - } - } - - return false; - } - - private static function legacyResponse(LegacyPathInfo $pathInfo): Response - { - return response() - ->view('legacy', ['includePath' => $pathInfo->path]) - ->header('Content-Type', $pathInfo->contentType); - } -} diff --git a/src/app/Http/Controllers/Controller.php b/src/app/Http/Controllers/Controller.php index a0a2a8a34..ce1176ddb 100644 --- a/src/app/Http/Controllers/Controller.php +++ b/src/app/Http/Controllers/Controller.php @@ -9,5 +9,7 @@ class Controller extends BaseController { - use AuthorizesRequests, DispatchesJobs, ValidatesRequests; + use AuthorizesRequests; + use DispatchesJobs; + use ValidatesRequests; } diff --git a/src/app/Http/Controllers/Legacy/LegacyAdminController.php b/src/app/Http/Controllers/Legacy/LegacyAdminController.php index 543d406e7..363a30c08 100644 --- a/src/app/Http/Controllers/Legacy/LegacyAdminController.php +++ b/src/app/Http/Controllers/Legacy/LegacyAdminController.php @@ -3,7 +3,7 @@ namespace App\Http\Controllers\Legacy; use App\Http\Controllers\Controller; -use App\Http\Controllers\CatchAllController; +use App\Http\Controllers\UserInterfaceController; use App\Interfaces\ServiceBodyRepositoryInterface; use App\Interfaces\UserRepositoryInterface; use App\Models\User; @@ -39,7 +39,7 @@ public function handle(Request $request) return $this->handleGetUserInfo($request); } - return CatchAllController::handle($request); + return UserInterfaceController::handle($request); } private function handleLogin(Request $request) diff --git a/src/app/Http/Controllers/Legacy/LegacyPathInfo.php b/src/app/Http/Controllers/Legacy/LegacyPathInfo.php index d64736eb3..462db9079 100644 --- a/src/app/Http/Controllers/Legacy/LegacyPathInfo.php +++ b/src/app/Http/Controllers/Legacy/LegacyPathInfo.php @@ -1,4 +1,5 @@ input('meeting_ids') ?? []; $meetingIds = is_string($meetingIds) ? array_map(fn ($id) => trim($id), explode(',', $meetingIds)) : $meetingIds; $meetingIds = ensure_integer_array($meetingIds); @@ -178,7 +180,7 @@ private function getSearchResults(Request $request, ?string $dataFormat = null): $geoWidthMiles = is_numeric($geoWidthMiles) ? floatval($geoWidthMiles) : null; if ($isAggregatorMode) { - $maxGeoWidthKilometers = legacy_config('aggregator_max_geo_width_km'); + $maxGeoWidthKilometers = file_config('aggregator_max_geo_width_km'); $maxGeoWidthMiles = $maxGeoWidthKilometers * 0.621371; $geoWidthKilometers = !is_null($geoWidthKilometers) && $geoWidthKilometers > $maxGeoWidthKilometers ? $maxGeoWidthKilometers : $geoWidthKilometers; $geoWidthMiles = !is_null($geoWidthMiles) && $geoWidthMiles > $maxGeoWidthMiles ? $maxGeoWidthMiles : $geoWidthMiles; @@ -195,15 +197,17 @@ private function getSearchResults(Request $request, ?string $dataFormat = null): $searchString = $request->input('SearchString'); $searchString = !is_null($searchString) ? trim($searchString) : null; - $searchString = strlen($searchString) > 2 || is_numeric($searchString) ? $searchString : null; + if (!is_null($searchString)) { + $searchString = mb_strlen($searchString) > 2 || is_numeric($searchString) ? $searchString : null; + } $searchStringIsAddress = !is_null($searchString) && $request->input('StringSearchIsAnAddress') == '1'; if (!is_null($searchString) && $searchStringIsAddress) { - $googleApiKey = legacy_config('google_api_key'); + $googleApiKey = bmlt_config('googleApiKey'); if (is_null($googleApiKey)) { abort(400, 'A google api key must be configured to use StringSearchIsAnAddress.'); } - $regionBias = legacy_config('region_bias'); + $regionBias = bmlt_config('regionBias'); if (is_string($regionBias) && is_numeric($searchString)) { // when it's numeric, like a postcode, add $regionBias directly $searchString .= ' ' . $regionBias; @@ -235,12 +239,12 @@ private function getSearchResults(Request $request, ?string $dataFormat = null): $searchStringRadius = $request->input('SearchStringRadius'); if (is_null($searchStringRadius) || !is_numeric($searchStringRadius)) { - $nNearestAuto = abs(legacy_config('number_of_meetings_for_auto')) * -1; - $geoWidthMiles = legacy_config('distance_units') == 'mi' ? $nNearestAuto : null; - $geoWidthKilometers = legacy_config('distance_units') != 'mi' ? $nNearestAuto : null; + $nNearestAuto = abs(bmlt_config('numberOfMeetingsForAuto')) * -1; + $geoWidthMiles = bmlt_config('distanceUnits') == 'mi' ? $nNearestAuto : null; + $geoWidthKilometers = bmlt_config('distanceUnits') != 'mi' ? $nNearestAuto : null; } else { - $geoWidthMiles = legacy_config('distance_units') == 'mi' ? floatval($searchStringRadius) : null; - $geoWidthKilometers = legacy_config('distance_units') != 'mi' ? floatval($searchStringRadius) : null; + $geoWidthMiles = bmlt_config('distanceUnits') == 'mi' ? floatval($searchStringRadius) : null; + $geoWidthKilometers = bmlt_config('distanceUnits') != 'mi' ? floatval($searchStringRadius) : null; } $searchString = null; @@ -258,7 +262,7 @@ private function getSearchResults(Request $request, ?string $dataFormat = null): $sortKeys = $request->input('sort_keys'); $sortKeys = empty($sortKeys) ? null : explode(',', $sortKeys); if (is_null($sortKeys)) { - $sortAlias = $request->input('sort_key') ?? legacy_config('default_sort_key'); + $sortAlias = $request->input('sort_key') ?? bmlt_config('defaultSortKey'); if (!is_null($sortAlias)) { if ($sortAlias == 'weekday') { $sortKeys = ['weekday_tinyint', 'location_municipality', 'location_city_subsection', 'start_time', 'location_neighborhood']; @@ -355,7 +359,7 @@ private function getSearchResults(Request $request, ?string $dataFormat = null): // This code to calculate the formats fields is really inefficient, but necessary because // we don't have foreign keys between the meetings and formats tables. - $langEnum = $request->input('lang_enum', config('app.locale')); + $langEnum = $request->input('lang_enum', App::currentLocale()); $formats = $this->formatRepository->search( rootServersInclude: $rootServersInclude, rootServersExclude: $rootServersExclude, @@ -391,7 +395,7 @@ private function getSearchResults(Request $request, ?string $dataFormat = null): private function getFormats(Request $request): BaseJsonResponse { - $isAggregatorMode = (bool)legacy_config('aggregator_mode_enabled'); + $isAggregatorMode = (bool)file_config('aggregator_mode_enabled'); $rootServersInclude = null; $rootServersExclude = null; @@ -414,7 +418,7 @@ private function getFormats(Request $request): BaseJsonResponse $formatsExclude = collect($formatIds)->filter(fn($r) => $r < 0)->map(fn($r) => abs($r))->toArray(); $formatsExclude = count($formatsExclude) ? $formatsExclude : null; - $langEnums = $request->input('lang_enum', config('app.locale')); + $langEnums = $request->input('lang_enum', App::currentLocale()); if (!is_array($langEnums)) { $langEnums = [$langEnums]; } @@ -461,7 +465,7 @@ private function getServiceBodies(Request $request): BaseJsonResponse $rootServersInclude = null; $rootServersExclude = null; - if (legacy_config('aggregator_mode_enabled')) { + if (file_config('aggregator_mode_enabled')) { $rootServerIds = $request->input('root_server_ids', []); $rootServerIds = ensure_integer_array($rootServerIds); $rootServersInclude = collect($rootServerIds)->filter(fn($r) => $r > 0)->map(fn($r) => $r)->toArray(); @@ -541,32 +545,29 @@ private function getServerInfo($request): BaseJsonResponse 'version' => config('app.version'), 'versionInt' => strval((intval($versionArray[0]) * 1000000) + (intval($versionArray[1]) * 1000) + intval(strstr($versionArray[2], '-', true) ?: $versionArray[2])), 'langs' => collect(scandir(base_path('lang')))->reject(fn ($dir) => str_starts_with($dir, '.'))->sort()->join(','), - 'nativeLang' => config('app.locale'), - 'centerLongitude' => strval(legacy_config('search_spec_map_center_longitude')), - 'centerLatitude' => strval(legacy_config('search_spec_map_center_latitude')), - 'centerZoom' => strval(legacy_config('search_spec_map_center_zoom')), - 'defaultDuration' => legacy_config('default_duration_time'), - 'regionBias' => legacy_config('region_bias'), + 'nativeLang' => App::currentLocale(), + 'centerLongitude' => strval(bmlt_config('searchSpecMapCenterLongitude')), + 'centerLatitude' => strval(bmlt_config('searchSpecMapCenterLatitude')), + 'centerZoom' => strval(bmlt_config('searchSpecMapCenterZoom')), + 'defaultDuration' => bmlt_config('defaultDurationTime'), + 'regionBias' => bmlt_config('regionBias'), 'charSet' => 'UTF-8', - 'distanceUnits' => legacy_config('distance_units'), - 'semanticAdmin' => legacy_config('enable_semantic_admin') ? '1' : '0', - 'emailEnabled' => legacy_config('enable_email_contact') ? '1' : '0', - 'emailIncludesServiceBodies' => legacy_config('include_service_body_admin_on_emails') ? '1' : '0', - 'changesPerMeeting' => strval(legacy_config('change_depth_for_meetings')), - 'meeting_states_and_provinces' => implode(',', legacy_config('meeting_states_and_provinces', [])), - 'meeting_counties_and_sub_provinces' => implode(',', legacy_config('meeting_counties_and_sub_provinces', [])), + 'distanceUnits' => bmlt_config('distanceUnits'), + 'semanticAdmin' => '1', // Yap uses this flag to determine legacy auth so we must keep it. + 'changesPerMeeting' => strval(bmlt_config('changeDepthForMeetings')), + 'meeting_states_and_provinces' => implode(',', bmlt_config('meetingStatesAndProvinces', [])), + 'meeting_counties_and_sub_provinces' => implode(',', bmlt_config('meetingCountiesAndSubProvinces', [])), 'available_keys' => $this->meetingRepository->getFieldKeys()->map(fn ($value) => $value['key'])->merge(['root_server_uri', 'format_shared_id_list'])->join(','), - 'google_api_key' => legacy_config('aggregator_mode_enabled') ? null : legacy_config('google_api_key', ''), + 'google_api_key' => file_config('aggregator_mode_enabled') ? null : bmlt_config('googleApiKey', ''), 'dbVersion' => $this->migrationRepository->getLastMigration()['migration'], - 'dbPrefix' => legacy_config('db_prefix'), - 'meeting_time_zones_enabled' => legacy_config('meeting_time_zones_enabled') ? '1' : '0', + 'dbPrefix' => file_config('db_prefix'), 'phpVersion' => phpversion(), - 'auto_geocoding_enabled' => legacy_config('auto_geocoding_enabled'), - 'county_auto_geocoding_enabled' => legacy_config('county_auto_geocoding_enabled'), - 'zip_auto_geocoding_enabled' => legacy_config('zip_auto_geocoding_enabled'), + 'auto_geocoding_enabled' => bmlt_config('autoGeocodingEnabled'), + 'county_auto_geocoding_enabled' => bmlt_config('countyAutoGeocodingEnabled'), + 'zip_auto_geocoding_enabled' => bmlt_config('zipAutoGeocodingEnabled'), 'commit' => config('app.commit'), - 'default_closed_status' => legacy_config('default_closed_status'), - 'aggregator_mode_enabled' => legacy_config('aggregator_mode_enabled') + 'default_closed_status' => bmlt_config('defaultClosedStatus'), + 'aggregator_mode_enabled' => file_config('aggregator_mode_enabled') ]]); } @@ -693,7 +694,7 @@ private function getNawsDump($request): StreamedResponse }) ->reject(fn ($meeting) => is_null($meeting)); $meetings = $meetings->concat($deletedMeetings); - $allFormats = $this->formatRepository->search(langEnums: [legacy_config('language')], showAll: true) + $allFormats = $this->formatRepository->search(langEnums: [App::currentLocale()], showAll: true) ->reject(fn ($fmt) => is_null($fmt->key_string) || empty(trim($fmt->key_string))); $formatIdToWorldId = $allFormats->mapWithKeys(fn ($fmt, $_) => [$fmt->shared_id_bigint => $fmt->worldid_mixed]); $formatIdToKeyString = $allFormats->mapWithKeys(fn ($fmt, $_) => [$fmt->shared_id_bigint => $fmt->key_string]); @@ -937,7 +938,7 @@ private function getNawsClosed($meetingFormats) if (in_array('OPEN', $meetingFormats)) { return 'OPEN'; } - return legacy_config('default_closed_status') ? 'CLOSED' : 'OPEN'; + return bmlt_config('defaultClosedStatus') ? 'CLOSED' : 'OPEN'; } // Meeting times will be of the form 19:30:00. Convert to 1930 (which is what this format expects). @@ -945,7 +946,7 @@ private function getNawsTime($meeting) { $t = explode(':', $meeting->start_time); if (is_array($t) && count($t) > 1) { - return $t[0].$t[1]; + return $t[0] . $t[1]; } else { return $t; } diff --git a/src/app/Http/Controllers/UserInterfaceController.php b/src/app/Http/Controllers/UserInterfaceController.php new file mode 100644 index 000000000..027ba2c77 --- /dev/null +++ b/src/app/Http/Controllers/UserInterfaceController.php @@ -0,0 +1,72 @@ +view('frontend', [ + 'autoGeocodingEnabled' => bmlt_config('autoGeocodingEnabled'), + 'baseUrl' => $request->getBaseurl(), + 'bmltTitle' => bmlt_config('bmltTitle'), + 'bmltNotice' => bmlt_config('bmltNotice'), + 'centerLongitude' => bmlt_config('searchSpecMapCenterLongitude'), + 'centerLatitude' => bmlt_config('searchSpecMapCenterLatitude'), + 'centerZoom' => bmlt_config('searchSpecMapCenterZoom'), + 'countyAutoGeocodingEnabled' => bmlt_config('countyAutoGeocodingEnabled'), + 'customFields' => self::getCustomFields(), + 'defaultClosedStatus' => bmlt_config('defaultClosedStatus'), + 'defaultDuration' => bmlt_config('defaultDurationTime'), + 'defaultLanguage' => App::currentLocale(), + 'distanceUnits' => bmlt_config('distanceUnits'), + 'googleApiKey' => bmlt_config('googleApiKey', ''), + 'isLanguageSelectorEnabled' => bmlt_config('enableLanguageSelector'), + 'languageMapping' => self::getLanguageMapping(), + 'formatLangNames' => bmlt_config('formatLangNames', []), + 'meetingStatesAndProvinces' => bmlt_config('meetingStatesAndProvinces', []), + 'meetingCountiesAndSubProvinces' => bmlt_config('meetingCountiesAndSubProvinces', []), + 'regionBias' => bmlt_config('regionBias'), + 'version' => config('app.version'), + 'zipAutoGeocodingEnabled' => bmlt_config('zipAutoGeocodingEnabled'), + ]); + } + + private static function getLanguageMapping(): array + { + return collect(scandir(base_path('lang'))) + ->reject(fn($dir) => str_starts_with($dir, '.')) + ->sort() + ->mapWithKeys(fn($langCode) => [$langCode => __('language_name.name', [], $langCode)]) + ->toArray(); + } + + private static function getCustomFields(): Collection + { + $meetingRepository = resolve(MeetingRepositoryInterface::class); + $customFields = $meetingRepository->getCustomFields(); + return $meetingRepository->getDataTemplates() + ->reject(fn ($t) => !$customFields->contains($t->key)) + ->map(fn ($t) => [ + 'name' => $t->key, + 'displayName' => $t->field_prompt, + 'language' => $t->lang_enum + ]) + ->values(); + } +} diff --git a/src/app/Http/Kernel.php b/src/app/Http/Kernel.php index 899664162..43fd6dcbd 100644 --- a/src/app/Http/Kernel.php +++ b/src/app/Http/Kernel.php @@ -17,6 +17,7 @@ class Kernel extends HttpKernel protected $middleware = [ // \App\Http\Middleware\TrustHosts::class, \App\Http\Middleware\DatabaseMigrations::class, + \App\Http\Middleware\SetLocale::class, \App\Http\Middleware\TrustProxies::class, \Illuminate\Http\Middleware\HandleCors::class, \App\Http\Middleware\PreventRequestsDuringMaintenance::class, diff --git a/src/app/Http/Middleware/DatabaseMigrations.php b/src/app/Http/Middleware/DatabaseMigrations.php index a1da89061..c74b43253 100644 --- a/src/app/Http/Middleware/DatabaseMigrations.php +++ b/src/app/Http/Middleware/DatabaseMigrations.php @@ -46,13 +46,13 @@ public function handle(Request $request, Closure $next) return $next($request); } - private function migrationsShouldRun(): bool + public function migrationsShouldRun(): bool { if (!Schema::hasTable('migrations')) { return true; } - if (!$this->migrationRepository->migrationExists('2024_07_20_203802_fix_admin_user_owners')) { + if (!$this->migrationRepository->migrationExists('2025_12_31_233709_clean_orphaned_format_ids')) { return true; } diff --git a/src/app/Http/Middleware/SetLocale.php b/src/app/Http/Middleware/SetLocale.php new file mode 100644 index 000000000..6a0a1db19 --- /dev/null +++ b/src/app/Http/Middleware/SetLocale.php @@ -0,0 +1,17 @@ +setLocale(bmlt_config('language', 'en')); + return $next($request); + } +} diff --git a/src/app/Http/Resources/Admin/MeetingChangeResource.php b/src/app/Http/Resources/Admin/MeetingChangeResource.php index d9d1f6d3d..2103b87c3 100644 --- a/src/app/Http/Resources/Admin/MeetingChangeResource.php +++ b/src/app/Http/Resources/Admin/MeetingChangeResource.php @@ -11,6 +11,7 @@ class MeetingChangeResource extends JsonResource { use ChangeDetailsTrait; + private static bool $isRequestInitialized = false; private static Collection $allFormats; private static Collection $allServiceBodies; @@ -32,7 +33,7 @@ public function toArray($request): array 'dateString' => date('g:i A, n/j/Y', strtotime($this->change_date)), 'userName' => $this->user?->name_string ?? '', 'serviceBodyName' => $this->serviceBody?->name_string ?? '', - 'details' => $this->getChangeDetails(true), + 'details' => $this->getChangeDetails(asArray: true, ignoreVisibility: true), ]; } diff --git a/src/app/Http/Resources/Admin/MeetingResource.php b/src/app/Http/Resources/Admin/MeetingResource.php index 070289e3c..54a050ead 100644 --- a/src/app/Http/Resources/Admin/MeetingResource.php +++ b/src/app/Http/Resources/Admin/MeetingResource.php @@ -2,6 +2,7 @@ namespace App\Http\Resources\Admin; +use Illuminate\Support\Facades\App; use App\Http\Resources\JsonResource; use App\Models\Meeting; use App\Repositories\MeetingRepository; @@ -30,7 +31,20 @@ public static function resetStaticVariables() self::$hiddenFormatIds = null; self::$temporarilyClosedFormatId = null; } - + private function languagePriority($langEnum, $requestedLangEnum) + { + if ($langEnum === $requestedLangEnum) { + return 3; + } + if ($langEnum === (file_config('language') ?: App::currentLocale())) { + return 2; + } + return 1; + } + private function getTargetLanguage($request) + { + return $request->lang; + } public function toArray($request) { if (!self::$isRequestInitialized) { @@ -47,9 +61,17 @@ public function toArray($request) self::$hiddenFormatIds = collect([self::$virtualFormatId, self::$hybridFormatId, self::$temporarilyClosedFormatId]); self::$isRequestInitialized = true; } - - $meetingData = $this->data - ->mapWithKeys(fn ($data, $_) => [$data->key => $data->data_string]) + $requestedLangEnum = $this->getTargetLanguage($request) ?? (file_config('language') ?: App::currentLocale()); + $meetingData = collect($this->data->reduce(function ($carry, $item) use ($requestedLangEnum) { + if (!isset($carry[0][$item->key])) { + $carry[0][$item->key] = $item->data_string; + $carry[1][$item->key] = $item->lang_enum; + } elseif ($this->languagePriority($item->lang_enum, $requestedLangEnum) > $this->languagePriority($carry[0][$item->key], $requestedLangEnum)) { + $carry[0][$item->key] = $item->data_string; + $carry[1][$item->key] = $item->lang_enum; + } + return $carry; + }, [[], []])[0]) ->toBase() ->merge( $this->longdata diff --git a/src/app/Http/Resources/Admin/SettingResource.php b/src/app/Http/Resources/Admin/SettingResource.php new file mode 100644 index 000000000..2abfe6e64 --- /dev/null +++ b/src/app/Http/Resources/Admin/SettingResource.php @@ -0,0 +1,26 @@ +name] = $setting->value; + } + + return $settings; + } +} diff --git a/src/app/Http/Resources/Admin/UserResource.php b/src/app/Http/Resources/Admin/UserResource.php index 8810031f6..afab69a30 100644 --- a/src/app/Http/Resources/Admin/UserResource.php +++ b/src/app/Http/Resources/Admin/UserResource.php @@ -24,6 +24,8 @@ public function toArray($request) 'description' => $this->description_string, 'email' => $this->email_address_string, 'ownerId' => $this->owner_id_bigint == -1 ? null : $this->owner_id_bigint, + 'targetLanguage' => $this->target_language ?? '', + 'lastLoginAt' => $this->last_access_datetime?->year > 1970 ? $this->last_access_datetime : null, ]; } } diff --git a/src/app/Http/Resources/Query/FormatResource.php b/src/app/Http/Resources/Query/FormatResource.php index 0f891fb20..52acbfb03 100644 --- a/src/app/Http/Resources/Query/FormatResource.php +++ b/src/app/Http/Resources/Query/FormatResource.php @@ -14,7 +14,7 @@ class FormatResource extends JsonResource */ public function toArray($request) { - $isAggregatorModeEnabled = (bool)legacy_config('aggregator_mode_enabled'); + $isAggregatorModeEnabled = (bool)file_config('aggregator_mode_enabled'); return [ 'key_string' => $this->key_string, diff --git a/src/app/Http/Resources/Query/MeetingChangeResource.php b/src/app/Http/Resources/Query/MeetingChangeResource.php index 3a8326093..11331c4bd 100644 --- a/src/app/Http/Resources/Query/MeetingChangeResource.php +++ b/src/app/Http/Resources/Query/MeetingChangeResource.php @@ -3,6 +3,7 @@ namespace App\Http\Resources\Query; use App\Http\Resources\JsonResource; +use App\Models\User; use App\Repositories\FormatRepository; use App\Repositories\ServiceBodyRepository; use App\Http\Resources\Traits\ChangeDetailsTrait; @@ -11,9 +12,13 @@ class MeetingChangeResource extends JsonResource { use ChangeDetailsTrait; + private static bool $isRequestInitialized = false; private static Collection $allFormats; private static Collection $allServiceBodies; + private static ?Collection $serviceBodyPermissions = null; + private static bool $userIsAuthenticated = false; + private static bool $userIsAdmin = false; private bool $isBeforeObjectLoaded = false; private ?array $cachedBeforeObject; @@ -25,7 +30,7 @@ class MeetingChangeResource extends JsonResource 'c_comdef_meeting' => 'meeting', 'c_comdef_format' => 'format', 'c_comdef_user' => 'user', - 'c_comdef_service_body'=> 'service_body', + 'c_comdef_service_body' => 'service_body', ]; private static array $changeTypeToStrMap = [ @@ -39,6 +44,9 @@ class MeetingChangeResource extends JsonResource public static function resetStaticVariables() { self::$isRequestInitialized = false; + self::$serviceBodyPermissions = null; + self::$userIsAuthenticated = false; + self::$userIsAdmin = false; } public function toArray($request) @@ -65,13 +73,26 @@ public function toArray($request) ]; } - private function initializeRequest() + private function initializeRequest($request) { $formatRepository = new FormatRepository(); self::$allFormats = $formatRepository->search(showAll: true)->groupBy(['shared_id_bigint', 'lang_enum'], preserveKeys: true); $serviceBodyRepository = new ServiceBodyRepository(); self::$allServiceBodies = $serviceBodyRepository->search()->mapWithKeys(fn ($sb) => [$sb->id_bigint => $sb]); + + // Permissions + $user = $request->user(); + if (!is_null($user) && $user->user_level_tinyint != User::USER_LEVEL_DEACTIVATED) { + self::$userIsAuthenticated = true; + if ($user->user_level_tinyint == User::USER_LEVEL_ADMIN) { + self::$userIsAdmin = true; + } else { + self::$serviceBodyPermissions = $serviceBodyRepository + ->getAssignedServiceBodyIds($user->id_bigint) + ->mapWithKeys(fn ($sbId, $_) => [$sbId => null]); + } + } } private function getJsonDataArray(): array @@ -94,6 +115,7 @@ private function getJsonDataArray(): array private function convertObjectToArray($meetingObject): array { $ret = collect([]); + $serviceBodyBigint = null; $mainValues = $meetingObject['main_table_values'] ?? null; if ($mainValues) { @@ -166,6 +188,8 @@ private function convertObjectToArray($meetingObject): array } $dataTableValues = $meetingObject['data_table_values'] ?? []; + $userHasPermission = self::$userIsAuthenticated && (self::$userIsAdmin || self::$serviceBodyPermissions?->has($serviceBodyBigint)); + foreach ($dataTableValues as $data) { if (isset($data['key']) && $data['key'] == 'root_server_uri') { continue; @@ -173,7 +197,13 @@ private function convertObjectToArray($meetingObject): array if (!isset($data['data_string'])) { continue; } - $ret->put($data['key'], $data['data_string']); + + // Check visibility field - if visibility is 1 (protected) and user doesn't have permission, mask with asterisks + if (isset($data['visibility']) && $data['visibility'] == 1 && !$userHasPermission && !empty($data['data_string'])) { + $ret->put($data['key'], '********'); + } else { + $ret->put($data['key'], $data['data_string']); + } } return $ret->toArray(); diff --git a/src/app/Http/Resources/Query/MeetingResource.php b/src/app/Http/Resources/Query/MeetingResource.php index b7b3e307e..cfee711c8 100644 --- a/src/app/Http/Resources/Query/MeetingResource.php +++ b/src/app/Http/Resources/Query/MeetingResource.php @@ -37,6 +37,16 @@ public static function resetStaticVariables() self::$defaultDurationTime = null; self::$isAggregatorModeEnabled = false; } + private function languagePriority($langEnum, $requestedLangEnum) + { + if ($langEnum === $requestedLangEnum) { + return 3; + } + if ($langEnum === config('app.locale')) { + return 2; + } + return 1; + } /** * Transform the resource into an array. @@ -75,13 +85,21 @@ public function toArray($request) 'format_shared_id_list' => $this->getFormatSharedIdList(), 'root_server_id' => $this->getRootServerId(), ]; - + $requestedLangEnum = $request->lang_enum ?? config('app.locale'); // data table keys - $meetingData = $this->data->mapWithKeys(fn ($data, $_) => [$data->key => $data->data_string])->toBase() + $meetingData = collect($this->data->reduce(function ($carry, $item) use ($requestedLangEnum) { + if (!isset($carry[0][$item->key])) { + $carry[0][$item->key] = $item->data_string; + $carry[1][$item->key] = $item->lang_enum; + } elseif ($this->languagePriority($item->lang_enum, $requestedLangEnum) > $this->languagePriority($carry[0][$item->key], $requestedLangEnum)) { + $carry[0][$item->key] = $item->data_string; + $carry[1][$item->key] = $item->lang_enum; + } + return $carry; + }, [[], []])[0])->toBase() ->merge( - $this->longdata->mapWithKeys(fn ($data, $_) => [$data->key => $data->data_blob])->toBase() + $this->longdata->mapWithKeys(fn ($data, $_) => [$data->key.'|'.$data->lang_enum => $data->data_blob])->toBase() ); - foreach (self::$meetingDataTemplates as $meetingDataTemplate) { if (self::$hasDataFieldKeys && !self::$dataFieldKeys->has($meetingDataTemplate->key)) { continue; @@ -106,10 +124,10 @@ private function initializeRequest($request) $serviceBodyRepository = new ServiceBodyRepository(); // Default duration time - self::$defaultDurationTime = legacy_config('default_duration_time'); + self::$defaultDurationTime = bmlt_config('defaultDurationTime'); // Aggregator mode - self::$isAggregatorModeEnabled = (bool)legacy_config('aggregator_mode_enabled'); + self::$isAggregatorModeEnabled = (bool)file_config('aggregator_mode_enabled'); // Preload meeting data templates self::$meetingDataTemplates = $meetingRepository->getDataTemplates(); diff --git a/src/app/Http/Resources/Query/ServiceBodyResource.php b/src/app/Http/Resources/Query/ServiceBodyResource.php index e1d0ef879..a383bf863 100644 --- a/src/app/Http/Resources/Query/ServiceBodyResource.php +++ b/src/app/Http/Resources/Query/ServiceBodyResource.php @@ -23,8 +23,8 @@ public function toArray($request) 'url' => $this->uri_string ?? '', 'helpline' => $this->kml_file_uri_string ?? '', 'world_id' => $this->worldid_mixed ?? '', - 'contact_email' => $this->when(legacy_config('include_service_body_email_in_semantic'), $this->sb_meeting_email ?? ''), - 'root_server_id' => $this->when(legacy_config('aggregator_mode_enabled'), $this->root_server_id ?? '') + 'contact_email' => $this->when(bmlt_config('includeServiceBodyEmailInSemantic'), $this->sb_meeting_email ?? ''), + 'root_server_id' => $this->when(file_config('aggregator_mode_enabled'), $this->root_server_id ?? '') ]; } } diff --git a/src/app/Http/Resources/Query/TsmlMeetingResource.php b/src/app/Http/Resources/Query/TsmlMeetingResource.php index d1dacf8e8..0d4ea8c92 100644 --- a/src/app/Http/Resources/Query/TsmlMeetingResource.php +++ b/src/app/Http/Resources/Query/TsmlMeetingResource.php @@ -90,11 +90,12 @@ public function toArray($request): array ->filter() ->values() ->toArray(), - 'notes' => $allData['location_info'] ?? '', + 'location_notes' => $allData['location_info'] ?? '', + 'notes' => $allData['comments'] ?? '', 'coordinates' => $this->venue_type == 2 ? null : (($this->latitude && $this->longitude) ? "{$this->latitude},{$this->longitude}" : null), - 'slug' => \Str::slug($allData['meeting_name']), + 'slug' => \Str::slug($allData['meeting_name']) . '-' . $this->id_bigint, 'updated' => $this->updated_at ?? null, 'region' => $this->serviceBody->name_string ?? '', 'regions' => [$this->serviceBody->name_string ?? ''], diff --git a/src/app/Http/Resources/Traits/ChangeDetailsTrait.php b/src/app/Http/Resources/Traits/ChangeDetailsTrait.php index a1da3b09d..83efe0920 100644 --- a/src/app/Http/Resources/Traits/ChangeDetailsTrait.php +++ b/src/app/Http/Resources/Traits/ChangeDetailsTrait.php @@ -13,7 +13,7 @@ trait ChangeDetailsTrait 'c_comdef_meeting' => 'meeting', 'c_comdef_format' => 'format', 'c_comdef_user' => 'user', - 'c_comdef_service_body'=> 'service_body', + 'c_comdef_service_body' => 'service_body', ]; private static array $changeTypeToStrMap = [ @@ -23,7 +23,7 @@ trait ChangeDetailsTrait 'comdef_change_type_rollback' => 'rolled_back', ]; - public function getChangeDetails(bool $asArray = false): string|array + public function getChangeDetails(bool $asArray = false, bool $ignoreVisibility = false): string|array { $objectType = self::$objectClassToStrMap[$this->object_class_string]; $changeType = self::$changeTypeToStrMap[$this->change_type_enum]; @@ -69,12 +69,12 @@ public function getChangeDetails(bool $asArray = false): string|array $beforeValue = $beforeValues->get($key); $afterValue = $afterValues->get($key); if (is_array($afterValue)) { - $isVisible = $afterValue['visibility'] !== 1; + $isVisible = $ignoreVisibility || $afterValue['visibility'] !== 1; $fieldPrompt = $afterValue['field_prompt'] ?? $fieldName; $afterValue = $afterValue['data_string'] ?? null; } if (is_array($beforeValue)) { - if ($isVisible) { + if ($isVisible && !$ignoreVisibility) { $isVisible = $beforeValue['visibility'] !== 1; } if ($fieldPrompt == $key) { @@ -158,9 +158,9 @@ public function getChangeDetails(bool $asArray = false): string|array $afterValue = floatval($afterValue); } elseif ($key == 'start_time' || $key == 'duration_time') { $beforeValue = explode(':', $beforeValue); - $beforeValue = strval(intval($beforeValue[0])).':'.(intval($beforeValue[1]) < 10 ? '0' : '').strval(intval($beforeValue[1])); + $beforeValue = strval(intval($beforeValue[0])) . ':' . (intval($beforeValue[1]) < 10 ? '0' : '') . strval(intval($beforeValue[1])); $afterValue = explode(':', $afterValue); - $afterValue = strval(intval($afterValue[0])).':'.(intval($afterValue[1]) < 10 ? '0' : '').strval(intval($afterValue[1])); + $afterValue = strval(intval($afterValue[0])) . ':' . (intval($afterValue[1]) < 10 ? '0' : '') . strval(intval($afterValue[1])); if ($beforeValue == $afterValue) { continue; } diff --git a/src/app/Interfaces/FormatRepositoryInterface.php b/src/app/Interfaces/FormatRepositoryInterface.php index 568b7c2bf..22ee83813 100644 --- a/src/app/Interfaces/FormatRepositoryInterface.php +++ b/src/app/Interfaces/FormatRepositoryInterface.php @@ -3,6 +3,7 @@ namespace App\Interfaces; use App\Models\Format; +use App\Repositories\Import\FormatImportResult; use Illuminate\Support\Collection; interface FormatRepositoryInterface @@ -25,5 +26,5 @@ public function getTemporarilyClosedFormat(): Format; public function create(array $sharedFormatsValues): Format; public function update(int $sharedId, array $sharedFormatsValues): bool; public function delete(int $sharedId): bool; - public function import(int $rootServerId, Collection $externalObjects): void; + public function import(int $rootServerId, Collection $externalObjects): FormatImportResult; } diff --git a/src/app/Interfaces/MeetingRepositoryInterface.php b/src/app/Interfaces/MeetingRepositoryInterface.php index ea7992f04..878fa70fc 100644 --- a/src/app/Interfaces/MeetingRepositoryInterface.php +++ b/src/app/Interfaces/MeetingRepositoryInterface.php @@ -3,6 +3,7 @@ namespace App\Interfaces; use App\Models\Meeting; +use App\Repositories\Import\MeetingImportResult; use Illuminate\Support\Collection; interface MeetingRepositoryInterface @@ -50,6 +51,8 @@ public function getDataTemplates(): Collection; public function getBoundingBox(): array; public function create(array $values): Meeting; public function update(int $id, array $values): bool; + public function translate(int $id, array $values): bool; + public function setTargetLanguage(string $lang); public function delete(int $id): bool; - public function import(int $rootServerId, Collection $externalObjects): void; + public function import(int $rootServerId, Collection $externalObjects): MeetingImportResult; } diff --git a/src/app/Interfaces/RootServerRepositoryInterface.php b/src/app/Interfaces/RootServerRepositoryInterface.php index 58c21d477..eed96277f 100644 --- a/src/app/Interfaces/RootServerRepositoryInterface.php +++ b/src/app/Interfaces/RootServerRepositoryInterface.php @@ -3,6 +3,7 @@ namespace App\Interfaces; use App\Models\RootServer; +use App\Repositories\Import\RootServerImportResult; use Illuminate\Support\Collection; interface RootServerRepositoryInterface @@ -11,5 +12,5 @@ public function search(bool $eagerStatistics = false): Collection; public function create(array $values): RootServer; public function update(int $id, array $values): bool; public function delete(int $id): bool; - public function import(Collection $externalObjects): void; + public function import(Collection $externalObjects): RootServerImportResult; } diff --git a/src/app/Interfaces/ServiceBodyRepositoryInterface.php b/src/app/Interfaces/ServiceBodyRepositoryInterface.php index 2c1a603a4..346730aba 100644 --- a/src/app/Interfaces/ServiceBodyRepositoryInterface.php +++ b/src/app/Interfaces/ServiceBodyRepositoryInterface.php @@ -3,6 +3,7 @@ namespace App\Interfaces; use App\Models\ServiceBody; +use App\Repositories\Import\ServiceBodyImportResult; use Illuminate\Support\Collection; interface ServiceBodyRepositoryInterface @@ -23,5 +24,5 @@ public function getAdminServiceBodyIds(int $userId): Collection; public function getChildren(array $parents): array; public function getParents(array $children): array; public function removeUser(int $userId); - public function import(int $rootServerId, Collection $externalObjects): void; + public function import(int $rootServerId, Collection $externalObjects): ServiceBodyImportResult; } diff --git a/src/app/Interfaces/SettingRepositoryInterface.php b/src/app/Interfaces/SettingRepositoryInterface.php new file mode 100644 index 000000000..bfad91426 --- /dev/null +++ b/src/app/Interfaces/SettingRepositoryInterface.php @@ -0,0 +1,14 @@ +map(fn($id) => trim($id))->toArray() - : ($meeting_states_and_provinces ?? []); - $config['meeting_counties_and_sub_provinces'] = isset($meeting_counties_and_sub_provinces) && is_string($meeting_counties_and_sub_provinces) - ? collect(explode(',', $meeting_counties_and_sub_provinces))->map(fn($id) => trim($id))->toArray() - : ($meeting_counties_and_sub_provinces ?? []); - $config['meeting_time_zones_enabled'] = isset($meeting_time_zones_enabled) && $meeting_time_zones_enabled; - $config['search_spec_map_center_longitude'] = isset($search_spec_map_center) && is_array($search_spec_map_center) && isset($search_spec_map_center['longitude']) ? $search_spec_map_center['longitude'] : -118.563659; - $config['search_spec_map_center_latitude'] = isset($search_spec_map_center) && is_array($search_spec_map_center) && isset($search_spec_map_center['latitude']) ? $search_spec_map_center['latitude'] : 34.235918; - $config['search_spec_map_center_zoom'] = isset($search_spec_map_center) && is_array($search_spec_map_center) && isset($search_spec_map_center['zoom']) ? $search_spec_map_center['zoom'] : 6; - $config['number_of_meetings_for_auto'] = isset($number_of_meetings_for_auto) && is_numeric($number_of_meetings_for_auto) ? intval($number_of_meetings_for_auto) : 10; - $config['auto_geocoding_enabled'] = isset($auto_geocoding_enabled) ? boolval($auto_geocoding_enabled) : true; - $config['county_auto_geocoding_enabled'] = isset($county_auto_geocoding_enabled) ? boolval($county_auto_geocoding_enabled) : false; - $config['zip_auto_geocoding_enabled'] = isset($zip_auto_geocoding_enabled) ? boolval($zip_auto_geocoding_enabled) : false; - $config['new_ui_enabled'] = $new_ui_enabled ?? true; - // If default_closed_status is TRUE, meetings that don't explicitly have an OPEN or CLOSED format are assumed CLOSED for the NAWS export. - $config['default_closed_status'] = $g_defaultClosedStatus ?? true; - $config['enable_language_selector'] = $g_enable_language_selector ?? false; - $config['aggregator_mode_enabled'] = $aggregator_mode_enabled ?? false; - $config['aggregator_max_geo_width_km'] = isset($aggregator_max_geo_width_km) && is_numeric($aggregator_max_geo_width_km) ? floatval($aggregator_max_geo_width_km) : 1000; - $config['include_service_body_email_in_semantic'] = $g_include_service_body_email_in_semantic ?? false; - $config['bmlt_title'] = $bmlt_title ?? ''; - $config['bmlt_notice'] = $bmlt_notice ?? ''; - - self::$config = $config; - self::$configLoaded = true; - } -} diff --git a/src/app/Models/Setting.php b/src/app/Models/Setting.php new file mode 100644 index 000000000..14c7b235c --- /dev/null +++ b/src/app/Models/Setting.php @@ -0,0 +1,55 @@ + is_null($value) ? null : json_decode($value, true), + set: fn ($value) => is_null($value) ? null : json_encode($this->cast($value, $this->type)), + ); + } + + private function cast($value, string $type): mixed + { + switch ($type) { + case self::TYPE_ARRAY: + if (is_array($value)) { + return $value; + } + if (is_string($value)) { + return $value === '' ? [] : array_map('trim', explode(',', $value)); + } + return []; + + case self::TYPE_BOOL: + return (bool) $value; + + case self::TYPE_INT: + return (int) $value; + + case self::TYPE_FLOAT: + return (float) $value; + + case self::TYPE_STRING: + default: + return (string) $value; + } + } +} diff --git a/src/app/Models/User.php b/src/app/Models/User.php index 92edbd3d5..65f9b3dd3 100644 --- a/src/app/Models/User.php +++ b/src/app/Models/User.php @@ -9,23 +9,27 @@ class User extends Model implements AuthenticatableContract { - use Authenticatable, HasApiTokens; + use Authenticatable; + use HasApiTokens; public const USER_LEVEL_ADMIN = 1; public const USER_LEVEL_SERVICE_BODY_ADMIN = 2; public const USER_LEVEL_DEACTIVATED = 4; public const USER_LEVEL_OBSERVER = 5; + public const USER_LEVEL_TRANSLATOR = 6; public const USER_TYPE_DEACTIVATED = 'deactivated'; public const USER_TYPE_ADMIN = 'admin'; public const USER_TYPE_SERVICE_BODY_ADMIN = 'serviceBodyAdmin'; public const USER_TYPE_OBSERVER = 'observer'; + public const USER_TYPE_TRANSLATOR = 'translator'; public const USER_LEVEL_TO_USER_TYPE_MAP = [ self::USER_LEVEL_DEACTIVATED => self::USER_TYPE_DEACTIVATED, self::USER_LEVEL_ADMIN => self::USER_TYPE_ADMIN, self::USER_LEVEL_SERVICE_BODY_ADMIN => self::USER_TYPE_SERVICE_BODY_ADMIN, self::USER_LEVEL_OBSERVER => self::USER_TYPE_OBSERVER, + self::USER_LEVEL_TRANSLATOR => self::USER_TYPE_TRANSLATOR, ]; public const USER_TYPE_TO_USER_LEVEL_MAP = [ @@ -33,6 +37,7 @@ class User extends Model implements AuthenticatableContract self::USER_TYPE_ADMIN => self::USER_LEVEL_ADMIN, self::USER_TYPE_SERVICE_BODY_ADMIN => self::USER_LEVEL_SERVICE_BODY_ADMIN, self::USER_TYPE_OBSERVER => self::USER_LEVEL_OBSERVER, + self::USER_TYPE_TRANSLATOR => self::USER_LEVEL_TRANSLATOR, ]; public const FIELDS = [ @@ -43,6 +48,7 @@ class User extends Model implements AuthenticatableContract 'login_string', 'password_string', 'owner_id_bigint', + 'target_language' ]; protected $table = 'comdef_users'; @@ -50,6 +56,10 @@ class User extends Model implements AuthenticatableContract public $timestamps = false; protected $fillable = self::FIELDS; + protected $casts = [ + 'last_access_datetime' => 'datetime', + ]; + public function getAuthPassword() { return $this->password_string; @@ -70,6 +80,11 @@ public function isServiceBodyAdmin(): bool return $this->user_level_tinyint == self::USER_LEVEL_SERVICE_BODY_ADMIN; } + public function isTranslator(): bool + { + return $this->user_level_tinyint == self::USER_LEVEL_TRANSLATOR; + } + public function isDeactivated(): bool { return $this->user_level_tinyint == self::USER_LEVEL_DEACTIVATED; diff --git a/src/app/Policies/ChangePolicy.php b/src/app/Policies/ChangePolicy.php index fef091aa3..c255b99ab 100644 --- a/src/app/Policies/ChangePolicy.php +++ b/src/app/Policies/ChangePolicy.php @@ -9,7 +9,8 @@ class ChangePolicy { - use DeniesDeactivatedUser, HandlesAuthorization; + use DeniesDeactivatedUser; + use HandlesAuthorization; private ServiceBodyRepositoryInterface $serviceBodyRepository; diff --git a/src/app/Policies/DeniesDeactivatedUser.php b/src/app/Policies/DeniesDeactivatedUser.php index 12ede58e5..81933f4c2 100644 --- a/src/app/Policies/DeniesDeactivatedUser.php +++ b/src/app/Policies/DeniesDeactivatedUser.php @@ -1,4 +1,5 @@ update($user, $meeting); } + public function translate(User $user, Meeting $meeting) + { + if (file_config('aggregator_mode_enabled')) { + return false; + } + + if ($user->isAdmin()) { + return true; + } + + if ($user->isTranslator() || $user->isServiceBodyAdmin()) { + return $this->serviceBodyRepository->getAssignedServiceBodyIds($user->id_bigint)->contains($meeting->service_body_bigint); + } + return false; + } public function delete(User $user, Meeting $meeting) { - if (legacy_config('aggregator_mode_enabled')) { + if (file_config('aggregator_mode_enabled')) { return false; } diff --git a/src/app/Policies/ServiceBodyPolicy.php b/src/app/Policies/ServiceBodyPolicy.php index d03a3cfc6..448ab7d8a 100644 --- a/src/app/Policies/ServiceBodyPolicy.php +++ b/src/app/Policies/ServiceBodyPolicy.php @@ -9,7 +9,8 @@ class ServiceBodyPolicy { - use DeniesDeactivatedUser, HandlesAuthorization; + use DeniesDeactivatedUser; + use HandlesAuthorization; private ServiceBodyRepositoryInterface $serviceBodyRepository; @@ -34,7 +35,7 @@ public function view(User $user, ServiceBody $serviceBody) public function create(User $user) { - if (legacy_config('aggregator_mode_enabled')) { + if (file_config('aggregator_mode_enabled')) { return false; } @@ -43,7 +44,7 @@ public function create(User $user) public function update(User $user, ServiceBody $serviceBody) { - if (legacy_config('aggregator_mode_enabled')) { + if (file_config('aggregator_mode_enabled')) { return false; } @@ -65,7 +66,7 @@ public function partialUpdate(User $user, ServiceBody $serviceBody) public function delete(User $user, ServiceBody $serviceBody) { - if (legacy_config('aggregator_mode_enabled')) { + if (file_config('aggregator_mode_enabled')) { return false; } diff --git a/src/app/Policies/SettingPolicy.php b/src/app/Policies/SettingPolicy.php new file mode 100644 index 000000000..a24f7666d --- /dev/null +++ b/src/app/Policies/SettingPolicy.php @@ -0,0 +1,22 @@ +isAdmin(); + } + + public function update(User $user) + { + return $user->isAdmin(); + } +} diff --git a/src/app/Policies/UserPolicy.php b/src/app/Policies/UserPolicy.php index c60ba364a..58bc2aa57 100644 --- a/src/app/Policies/UserPolicy.php +++ b/src/app/Policies/UserPolicy.php @@ -7,7 +7,8 @@ class UserPolicy { - use DeniesDeactivatedUser, HandlesAuthorization; + use DeniesDeactivatedUser; + use HandlesAuthorization; public function viewAny(User $user) { diff --git a/src/app/Providers/AppServiceProvider.php b/src/app/Providers/AppServiceProvider.php index 84e2c731d..34bd4f181 100644 --- a/src/app/Providers/AppServiceProvider.php +++ b/src/app/Providers/AppServiceProvider.php @@ -3,7 +3,6 @@ namespace App\Providers; use Illuminate\Http\Resources\Json\JsonResource; -use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Log; use Illuminate\Support\ServiceProvider; diff --git a/src/app/Providers/RepositoryServiceProvider.php b/src/app/Providers/RepositoryServiceProvider.php index 195d92ceb..3ad8ec03b 100644 --- a/src/app/Providers/RepositoryServiceProvider.php +++ b/src/app/Providers/RepositoryServiceProvider.php @@ -8,6 +8,7 @@ use App\Interfaces\MigrationRepositoryInterface; use App\Interfaces\RootServerRepositoryInterface; use App\Interfaces\ServiceBodyRepositoryInterface; +use App\Interfaces\SettingRepositoryInterface; use App\Interfaces\UserRepositoryInterface; use App\Models\RootServer; use App\Repositories\ChangeRepository; @@ -16,6 +17,7 @@ use App\Repositories\MigrationRepository; use App\Repositories\RootServerRepository; use App\Repositories\ServiceBodyRepository; +use App\Repositories\SettingRepository; use App\Repositories\UserRepository; use Illuminate\Support\ServiceProvider; @@ -34,6 +36,7 @@ public function register() $this->app->bind(MigrationRepositoryInterface::class, MigrationRepository::class); $this->app->bind(RootServerRepositoryInterface::class, RootServerRepository::class); $this->app->bind(ServiceBodyRepositoryInterface::class, ServiceBodyRepository::class); + $this->app->bind(SettingRepositoryInterface::class, SettingRepository::class); $this->app->bind(UserRepositoryInterface::class, UserRepository::class); } diff --git a/src/app/Repositories/External/ExternalRootServer.php b/src/app/Repositories/External/ExternalRootServer.php index 9b90db6ff..181c7db5e 100644 --- a/src/app/Repositories/External/ExternalRootServer.php +++ b/src/app/Repositories/External/ExternalRootServer.php @@ -14,7 +14,7 @@ public function __construct(array $values) { $this->id = $this->validateInt($values, 'id'); $this->name = $this->validateString($values, 'name'); - $this->url = $this->validateUrl($values, 'rootURL'); + $this->url = $this->validateUrl($values, 'url'); } public function isEqual(RootServer $rootServer): bool diff --git a/src/app/Repositories/FormatRepository.php b/src/app/Repositories/FormatRepository.php index 18eae92bb..e2cfd167c 100644 --- a/src/app/Repositories/FormatRepository.php +++ b/src/app/Repositories/FormatRepository.php @@ -7,6 +7,7 @@ use App\Models\Format; use App\Models\Meeting; use App\Repositories\External\ExternalFormat; +use App\Repositories\Import\FormatImportResult; use Illuminate\Support\Collection; use Illuminate\Support\Facades\DB; @@ -112,7 +113,7 @@ public function create(array $sharedFormatsValues): Format foreach ($sharedFormatsValues as $values) { $values['shared_id_bigint'] = $sharedIdBigint; $format = Format::create($values); - if (!legacy_config('aggregator_mode_enabled')) { + if (!file_config('aggregator_mode_enabled')) { $this->saveChange(null, $format); } } @@ -136,7 +137,7 @@ public function update(int $sharedId, array $sharedFormatsValues): bool ->filter(fn ($values) => $values['lang_enum'] == $oldFormat->lang_enum) ->isEmpty(); if ($isDeleted) { - if (!legacy_config('aggregator_mode_enabled')) { + if (!file_config('aggregator_mode_enabled')) { $this->saveChange($oldFormat, null); } } @@ -146,7 +147,7 @@ public function update(int $sharedId, array $sharedFormatsValues): bool $values['shared_id_bigint'] = $sharedId; $newFormat = Format::create($values); $oldFormat = $oldFormats->get($newFormat->lang_enum); - if (!legacy_config('aggregator_mode_enabled')) { + if (!file_config('aggregator_mode_enabled')) { if (is_null($oldFormat)) { $this->saveChange(null, $newFormat); } else { @@ -166,7 +167,7 @@ public function delete(int $sharedId): bool if ($formats->isNotEmpty()) { foreach ($formats as $format) { $format->delete(); - if (!legacy_config('aggregator_mode_enabled')) { + if (!file_config('aggregator_mode_enabled')) { $this->saveChange($format, null); } } @@ -229,11 +230,13 @@ private function serializeForChange(Format $format): string ]); } - public function import(int $rootServerId, Collection $externalObjects): void + public function import(int $rootServerId, Collection $externalObjects): FormatImportResult { + $result = new FormatImportResult(); + // deleted formats $sourceIds = $externalObjects->pluck('id'); - Format::query() + $result->numDeleted = Format::query() ->where('root_server_id', $rootServerId) ->whereNotIn('source_id', $sourceIds) ->delete(); @@ -242,7 +245,7 @@ public function import(int $rootServerId, Collection $externalObjects): void foreach ($bySourceIdByLanguage as $sourceId => $byLanguage) { // deleted languages $languages = $byLanguage->keys(); - Format::query() + $result->numDeleted += Format::query() ->where('root_server_id', $rootServerId) ->where('source_id', $sourceId) ->whereNotIn('lang_enum', $languages) @@ -258,6 +261,7 @@ public function import(int $rootServerId, Collection $externalObjects): void if ($existingFormats->isEmpty()) { $values = $this->externalFormatToValuesArray($rootServerId, $sourceId, $externalFormats); $this->create($values); + $result->numCreated++; } else { $isDirty = $existingFormats->count() != $externalFormats->count(); if (!$isDirty) { @@ -274,9 +278,12 @@ public function import(int $rootServerId, Collection $externalObjects): void $sharedId = $existingFormats->first()->shared_id_bigint; $values = $this->externalFormatToValuesArray($rootServerId, $sourceId, $externalFormats); $this->update($sharedId, $values); + $result->numUpdated++; } } } + + return $result; } private function externalFormatToValuesArray(int $rootServerId, int $sourceId, Collection $externalFormats): array diff --git a/src/app/Repositories/Import/FormatImportResult.php b/src/app/Repositories/Import/FormatImportResult.php new file mode 100644 index 000000000..f7f63007c --- /dev/null +++ b/src/app/Repositories/Import/FormatImportResult.php @@ -0,0 +1,10 @@ + $meeting->id_bigint, 'key' => $t->key, 'field_prompt' => $t->field_prompt, - 'lang_enum' => $t->lang_enum, + 'lang_enum' => file_config('language') ?: App::currentLocale(), 'data_blob' => $fieldValue, 'visibility' => $t->visibility, ]); @@ -643,19 +645,70 @@ public function create(array $values): Meeting 'meetingid_bigint' => $meeting->id_bigint, 'key' => $t->key, 'field_prompt' => $t->field_prompt, - 'lang_enum' => $t->lang_enum, + 'lang_enum' => file_config('language') ?: App::currentLocale(), 'data_string' => $fieldValue, 'visibility' => $t->visibility, ]); } } - if (!legacy_config('aggregator_mode_enabled')) { + if (!file_config('aggregator_mode_enabled')) { $this->saveChange(null, $meeting); } return $meeting; }); } - + private function getSystemLanguage(): string + { + return file_config('language') ?: config('app.locale'); + } + public function setTargetLanguage($lang) + { + $this->targetLanguage = $lang; + } + private function getTargetLanguage(): string + { + return $this->targetLanguage ?? $this->getSystemLanguage(); + } + public function translate(int $id, array $values): bool + { + $dataTemplates = $this->getDataTemplates(); + return DB::transaction(function () use ($id, $values, $dataTemplates) { + $meeting = Meeting::find($id); + if (is_null($meeting)) { + return false; + } + MeetingData::query()->where('meetingid_bigint', $id) + ->where('lang_enum', $this->getTargetLanguage()) + ->whereIn('key', array_keys($values))->delete(); + MeetingLongData::query()->where('meetingid_bigint', $id) + ->where('lang_enum', $this->getTargetLanguage()) + ->whereIn('key', array_keys($values))->delete(); + foreach ($values as $fieldName => $fieldValue) { + $t = $dataTemplates->get($fieldName); + if (strlen($fieldValue) > 255) { + MeetingLongData::create([ + 'meetingid_bigint' => $meeting->id_bigint, + 'key' => $t->key, + 'field_prompt' => $t->field_prompt, + 'lang_enum' => $this->getTargetLanguage(), + 'data_blob' => $fieldValue, + 'visibility' => $t->visibility, + ]); + } else { + MeetingData::create([ + 'meetingid_bigint' => $meeting->id_bigint, + 'key' => $t->key, + 'field_prompt' => $t->field_prompt, + 'lang_enum' => $this->getTargetLanguage(), + 'data_string' => $fieldValue, + 'visibility' => $t->visibility, + ]); + } + } + return true; + }); + return false; + } public function update(int $id, array $values): bool { $values = collect($values); @@ -665,19 +718,37 @@ public function update(int $id, array $values): bool return DB::transaction(function () use ($id, $mainValues, $dataValues, $dataTemplates) { $meeting = Meeting::find($id); - $meeting->loadMissing(['data', 'longdata']); + //TODO: re-enable if needed + //$meeting->loadMissing(['data', 'longdata']); + if (!is_null($meeting)) { + $meetingDataValues = collect($meeting)->reject(fn ($_, $fieldName) => empty($value) || !$dataTemplates->has($fieldName)) + ->toBase(); Meeting::query()->where('id_bigint', $id)->update($mainValues); - MeetingData::query()->where('meetingid_bigint', $id)->delete(); - MeetingLongData::query()->where('meetingid_bigint', $id)->delete(); + + $oldData = MeetingData::query()->where('meetingid_bigint', $id) + ->where('lang_enum', $this->getSystemLanguage()) + ->whereIn('key', array_keys($dataValues->toArray()))->get() + ->merge( + MeetingLongData::query()->where('meetingid_bigint', $id) + ->where('lang_enum', $this->getSystemLanguage()) + ->whereIn('key', array_keys($dataValues->toArray()))->get() + )->keyby('key'); + MeetingData::query()->where('meetingid_bigint', $id)->where('lang_enum', $this->getSystemLanguage())->delete(); + MeetingLongData::query()->where('meetingid_bigint', $id)->where('lang_enum', $this->getSystemLanguage())->delete(); foreach ($dataValues as $fieldName => $fieldValue) { + if ($oldData->get($fieldName) != $fieldValue) { + $meetingDataValues->forget($fieldName); + MeetingData::query()->where('meetingid_bigint', $id)->where('key', $fieldName)->delete(); + MeetingLongData::query()->where('meetingid_bigint', $id)->where('key', $fieldName)->delete(); + } $t = $dataTemplates->get($fieldName); if (strlen($fieldValue) > 255) { MeetingLongData::create([ 'meetingid_bigint' => $meeting->id_bigint, 'key' => $t->key, 'field_prompt' => $t->field_prompt, - 'lang_enum' => $t->lang_enum, + 'lang_enum' => $this->getTargetLanguage(), 'data_blob' => $fieldValue, 'visibility' => $t->visibility, ]); @@ -686,13 +757,17 @@ public function update(int $id, array $values): bool 'meetingid_bigint' => $meeting->id_bigint, 'key' => $t->key, 'field_prompt' => $t->field_prompt, - 'lang_enum' => $t->lang_enum, + 'lang_enum' => $this->getTargetLanguage(), 'data_string' => $fieldValue, 'visibility' => $t->visibility, ]); } } - if (!legacy_config('aggregator_mode_enabled')) { + foreach ($meetingDataValues as $fieldName => $fieldValue) { + MeetingData::query()->where('meetingid_bigint', $id)->where('key', $fieldName)->delete(); + MeetingLongData::query()->where('meetingid_bigint', $id)->where('key', $fieldName)->delete(); + } + if (!file_config('aggregator_mode_enabled')) { $this->saveChange($meeting, Meeting::find($id)); } return true; @@ -710,7 +785,7 @@ public function delete(int $id): bool MeetingData::query()->where('meetingid_bigint', $meeting->id_bigint)->delete(); MeetingLongData::query()->where('meetingid_bigint', $meeting->id_bigint)->delete(); Meeting::query()->where('id_bigint', $meeting->id_bigint)->delete(); - if (!legacy_config('aggregator_mode_enabled')) { + if (!file_config('aggregator_mode_enabled')) { $this->saveChange($meeting, null); } return true; @@ -733,18 +808,18 @@ private function saveChange(?Meeting $beforeMeeting, ?Meeting $afterMeeting): vo // http request there will be a user, which will have a numeric ID. 'user_id_bigint' => request()?->user()?->id_bigint, 'service_body_id_bigint' => $afterMeeting?->service_body_bigint ?? $beforeMeeting->service_body_bigint, - 'lang_enum' => $beforeMeeting?->lang_enum ?: $afterMeeting?->lang_enum ?: legacy_config('language') ?: App::currentLocale(), + 'lang_enum' => $beforeMeeting?->lang_enum ?: $afterMeeting?->lang_enum ?: App::currentLocale(), 'object_class_string' => 'c_comdef_meeting', 'before_id_bigint' => $beforeMeeting?->id_bigint, - 'before_lang_enum' => !is_null($beforeMeeting) ? $beforeMeeting?->lang_enum ?: legacy_config('language') ?: App::currentLocale() : null, + 'before_lang_enum' => !is_null($beforeMeeting) ? $beforeMeeting?->lang_enum ?: App::currentLocale() : null, 'after_id_bigint' => $afterMeeting?->id_bigint, - 'after_lang_enum' => !is_null($afterMeeting) ? $afterMeeting?->lang_enum ?: legacy_config('language') ?: App::currentLocale() : null, + 'after_lang_enum' => !is_null($afterMeeting) ? $afterMeeting?->lang_enum ?: App::currentLocale() : null, 'change_type_enum' => is_null($beforeMeeting) ? 'comdef_change_type_new' : (is_null($afterMeeting) ? 'comdef_change_type_delete' : 'comdef_change_type_change'), 'before_object' => $beforeObject, 'after_object' => $afterObject, ]); - $changeLimit = legacy_config('change_depth_for_meetings'); + $changeLimit = bmlt_config('changeDepthForMeetings'); if (is_integer($changeLimit) && $changeLimit > 0) { $meetingId = $beforeMeeting?->id_bigint ?? $afterMeeting?->id_bigint; if (!is_null($meetingId)) { @@ -819,15 +894,16 @@ private function serializeForChange(Meeting $meeting): string ]); } - public function import(int $rootServerId, Collection $externalObjects): void + public function import(int $rootServerId, Collection $externalObjects): MeetingImportResult { + $result = new MeetingImportResult(); $sourceIds = $externalObjects->map(fn (ExternalMeeting $ex) => $ex->id); $meetingIds = Meeting::query() ->where('root_server_id', $rootServerId) ->whereNotIn('source_id', $sourceIds) ->pluck('id_bigint'); - Meeting::query()->whereIn('id_bigint', $meetingIds)->delete(); + $result->numDeleted = Meeting::query()->whereIn('id_bigint', $meetingIds)->delete(); MeetingData::query()->whereIn('meetingid_bigint', $meetingIds)->delete(); MeetingLongData::query()->whereIn('meetingid_bigint', $meetingIds)->delete(); @@ -852,18 +928,23 @@ public function import(int $rootServerId, Collection $externalObjects): void if (is_null($serviceBodyId)) { if (!is_null($db)) { $db->delete(); + $result->numOrphaned++; } continue; } if (is_null($db)) { $values = $this->externalMeetingToValuesArray($rootServerId, $serviceBodyId, $external, $formatSourceIdToSharedIdMap); - $this->create($values); + $this->create($values, 'en'); + $result->numCreated++; } else if (!$external->isEqual($db, $serviceBodyIdToSourceIdMap, $formatSharedIdToSourceIdMap)) { $values = $this->externalMeetingToValuesArray($rootServerId, $serviceBodyId, $external, $formatSourceIdToSharedIdMap); - $this->update($db->id_bigint, $values); + $this->update($db->id_bigint, $values, 'en'); + $result->numUpdated++; } } + + return $result; } private function castExternal($obj): ExternalMeeting diff --git a/src/app/Repositories/RootServerRepository.php b/src/app/Repositories/RootServerRepository.php index 9247ad382..7d7243f3f 100644 --- a/src/app/Repositories/RootServerRepository.php +++ b/src/app/Repositories/RootServerRepository.php @@ -8,6 +8,7 @@ use App\Models\MeetingLongData; use App\Models\RootServer; use App\Repositories\External\ExternalRootServer; +use App\Repositories\Import\RootServerImportResult; use Illuminate\Support\Collection; class RootServerRepository implements RootServerRepositoryInterface @@ -49,24 +50,25 @@ public function delete(int $id): bool return false; } - public function import(Collection $externalObjects): void + public function import(Collection $externalObjects): RootServerImportResult { + $result = new RootServerImportResult(); $ignoreRootServerUrls = config('aggregator.ignore_root_servers'); $externalObjects = $externalObjects->reject(fn (ExternalRootServer $ex) => in_array($ex->url, $ignoreRootServerUrls)); $sourceIds = $externalObjects->map(fn (ExternalRootServer $ex) => $ex->id); - RootServer::query()->whereNotIn('source_id', $sourceIds)->delete(); + $result->numDeleted = RootServer::query()->whereNotIn('source_id', $sourceIds)->delete(); // TODO test these MeetingData::query() ->whereNot('meetingid_bigint', 0) ->whereNotIn('meetingid_bigint', function ($query) { - $query->select('id_bigint')->from((new Meeting)->getTable()); + $query->select('id_bigint')->from((new Meeting())->getTable()); })->delete(); MeetingLongData::query() ->whereNot('meetingid_bigint', 0) ->whereNotIn('meetingid_bigint', function ($query) { - $query->select('id_bigint')->from((new Meeting)->getTable()); + $query->select('id_bigint')->from((new Meeting())->getTable()); })->delete(); foreach ($externalObjects as $externalRoot) { @@ -75,10 +77,14 @@ public function import(Collection $externalObjects): void $values = ['source_id' => $externalRoot->id, 'name' => $externalRoot->name, 'url' => $externalRoot->url]; if (is_null($dbRoot)) { $this->create($values); + $result->numCreated++; } else if (!$externalRoot->isEqual($dbRoot)) { $this->update($dbRoot->id, $values); + $result->numUpdated++; } } + + return $result; } private function castExternalRootServer($obj): ExternalRootServer diff --git a/src/app/Repositories/ServiceBodyRepository.php b/src/app/Repositories/ServiceBodyRepository.php index 7c6d2abdc..c7515e051 100644 --- a/src/app/Repositories/ServiceBodyRepository.php +++ b/src/app/Repositories/ServiceBodyRepository.php @@ -7,6 +7,7 @@ use App\Models\RootServer; use App\Models\ServiceBody; use App\Repositories\External\ExternalServiceBody; +use App\Repositories\Import\ServiceBodyImportResult; use Illuminate\Database\Eloquent\Builder; use Illuminate\Support\Collection; use Illuminate\Support\Facades\App; @@ -56,7 +57,7 @@ public function create(array $values): ServiceBody { return DB::transaction(function () use ($values) { $serviceBody = ServiceBody::create($values); - if (!legacy_config('aggregator_mode_enabled')) { + if (!file_config('aggregator_mode_enabled')) { $this->saveChange(null, $serviceBody); } return $serviceBody; @@ -69,7 +70,7 @@ public function update(int $id, array $values): bool $serviceBody = ServiceBody::find($id); if (!is_null($serviceBody)) { ServiceBody::query()->where('id_bigint', $id)->update($values); - if (!legacy_config('aggregator_mode_enabled')) { + if (!file_config('aggregator_mode_enabled')) { $this->saveChange($serviceBody, ServiceBody::find($id)); } return true; @@ -84,7 +85,7 @@ public function delete(int $id): bool $serviceBody = ServiceBody::find($id); if (!is_null($serviceBody)) { $serviceBody->delete(); - if (!legacy_config('aggregator_mode_enabled')) { + if (!file_config('aggregator_mode_enabled')) { $this->saveChange($serviceBody, null); } return true; @@ -105,12 +106,12 @@ private function saveChange(?ServiceBody $beforeServiceBody, ?ServiceBody $after Change::create([ 'user_id_bigint' => request()->user()->id_bigint, 'service_body_id_bigint' => $afterServiceBody?->id_bigint ?? $beforeServiceBody->id_bigint, - 'lang_enum' => $beforeServiceBody?->lang_enum ?: $afterServiceBody?->lang_enum ?: legacy_config('language') ?: App::currentLocale(), + 'lang_enum' => $beforeServiceBody?->lang_enum ?: $afterServiceBody?->lang_enum ?: App::currentLocale(), 'object_class_string' => 'c_comdef_service_body', 'before_id_bigint' => $beforeServiceBody?->id_bigint, - 'before_lang_enum' => !is_null($beforeServiceBody) ? $beforeServiceBody?->lang_enum ?: legacy_config('language') ?: App::currentLocale() : null, + 'before_lang_enum' => !is_null($beforeServiceBody) ? $beforeServiceBody?->lang_enum ?: App::currentLocale() : null, 'after_id_bigint' => $afterServiceBody?->id_bigint, - 'after_lang_enum' => !is_null($afterServiceBody) ? $afterServiceBody?->lang_enum ?: legacy_config('language') ?: App::currentLocale() : null, + 'after_lang_enum' => !is_null($afterServiceBody) ? $afterServiceBody?->lang_enum ?: App::currentLocale() : null, 'change_type_enum' => is_null($beforeServiceBody) ? 'comdef_change_type_new' : (is_null($afterServiceBody) ? 'comdef_change_type_delete' : 'comdef_change_type_change'), 'before_object' => $beforeObject, 'after_object' => $afterObject, @@ -128,7 +129,7 @@ private function serializeForChange(ServiceBody $serviceBody): string $serviceBody->worldid_mixed ?? '', $serviceBody->name_string, $serviceBody->description_string, - $serviceBody->lang_enum ?? legacy_config('language') ?? App::currentLocale(), + $serviceBody->lang_enum ?? App::currentLocale(), $serviceBody->sb_type ?? '', $serviceBody->sb_owner ?? '', $serviceBody->sb_owner_2 ?? '', @@ -235,14 +236,15 @@ public function removeUser(int $userId) } } - public function import(int $rootServerId, Collection $externalObjects): void + public function import(int $rootServerId, Collection $externalObjects): ServiceBodyImportResult { + $result = new ServiceBodyImportResult(); $rootServer = RootServer::query()->where('id', $rootServerId)->firstOrFail(); $ignoreServiceBodyIds = collect(config('aggregator.ignore_service_bodies'))->get($rootServer->source_id, []); $externalObjects = $externalObjects->reject(fn ($ex) => in_array($ex->id, $ignoreServiceBodyIds)); $sourceIds = $externalObjects->map(fn (ExternalServiceBody $ex) => $ex->id); - ServiceBody::query() + $result->numDeleted = ServiceBody::query() ->where('root_server_id', $rootServerId) ->whereNotIn('source_id', $sourceIds) ->delete(); @@ -258,11 +260,13 @@ public function import(int $rootServerId, Collection $externalObjects): void if (is_null($db)) { $values = $this->externalServiceBodyToValuesArray($rootServerId, $external); $bySourceId->put($external->id, $this->create($values)); + $result->numCreated++; } else if (!$external->isEqual($db)) { $values = $this->externalServiceBodyToValuesArray($rootServerId, $external); $this->update($db->id_bigint, $values); $db->refresh(); $bySourceId->put($external->id, $db); + $result->numUpdated++; } } @@ -276,6 +280,7 @@ public function import(int $rootServerId, Collection $externalObjects): void if ($db->sb_owner !== 0) { $db->sb_owner = 0; $db->save(); + $result->numReassigned++; } continue; } @@ -287,8 +292,11 @@ public function import(int $rootServerId, Collection $externalObjects): void if ($db->sb_owner != $parent->id_bigint) { $db->sb_owner = $parent->id_bigint; $db->save(); + $result->numReassigned++; } } + + return $result; } private function castExternal($obj): ExternalServiceBody diff --git a/src/app/Repositories/SettingRepository.php b/src/app/Repositories/SettingRepository.php new file mode 100644 index 000000000..edde71cc9 --- /dev/null +++ b/src/app/Repositories/SettingRepository.php @@ -0,0 +1,46 @@ +where('name', $name)->first(); + } + + public function getAll(): Collection + { + return Setting::all(); + } + + public function update(string $key, $value): bool + { + $setting = Setting::updateOrCreate( + ['name' => $key], + ['value' => $value] + ); + + return $setting->wasRecentlyCreated || $setting->wasChanged(); + } + + public function updateMultiple(array $keyValuePairs): bool + { + return DB::transaction(function () use ($keyValuePairs) { + $success = true; + + foreach ($keyValuePairs as $key => $value) { + if (!$this->update($key, $value)) { + $success = false; + } + } + + return $success; + }); + } +} diff --git a/src/app/Repositories/UserRepository.php b/src/app/Repositories/UserRepository.php index 869fbb668..977a522fe 100644 --- a/src/app/Repositories/UserRepository.php +++ b/src/app/Repositories/UserRepository.php @@ -90,7 +90,6 @@ public function delete(int $id): bool return false; }); } - private function saveChange(?User $beforeUser, ?User $afterUser): void { $beforeObject = !is_null($beforeUser) ? $this->serializeForChange($beforeUser) : null; @@ -103,12 +102,12 @@ private function saveChange(?User $beforeUser, ?User $afterUser): void Change::create([ 'user_id_bigint' => request()->user()?->id_bigint ?? $beforeUser?->id_bigint ?? $afterUser?->id_bigint, 'service_body_id_bigint' => $afterUser?->id_bigint ?? $beforeUser->id_bigint, - 'lang_enum' => $beforeUser?->lang_enum ?: $afterUser?->lang_enum ?: legacy_config('language') ?: App::currentLocale(), + 'lang_enum' => $beforeUser?->lang_enum ?: $afterUser?->lang_enum ?: App::currentLocale(), 'object_class_string' => 'c_comdef_user', 'before_id_bigint' => $beforeUser?->id_bigint, - 'before_lang_enum' => !is_null($beforeUser) ? $beforeUser?->lang_enum ?: legacy_config('language') ?: App::currentLocale() : null, + 'before_lang_enum' => !is_null($beforeUser) ? $beforeUser?->lang_enum ?: App::currentLocale() : null, 'after_id_bigint' => $afterUser?->id_bigint, - 'after_lang_enum' => !is_null($afterUser) ? $afterUser?->lang_enum ?: legacy_config('language') ?: App::currentLocale() : null, + 'after_lang_enum' => !is_null($afterUser) ? $afterUser?->lang_enum ?: App::currentLocale() : null, 'change_type_enum' => is_null($beforeUser) ? 'comdef_change_type_new' : (is_null($afterUser) ? 'comdef_change_type_delete' : 'comdef_change_type_change'), 'before_object' => $beforeObject, 'after_object' => $afterObject, diff --git a/src/app/Rules/FormatTranslationKey.php b/src/app/Rules/FormatTranslationKey.php new file mode 100644 index 000000000..caa6566be --- /dev/null +++ b/src/app/Rules/FormatTranslationKey.php @@ -0,0 +1,69 @@ +formatRepository = $formatRepository; + $this->formatId = $formatId; + } + + public function validate(string $attribute, mixed $value, Closure $fail): void + { + $translation = $this->data['translations'][intval(explode('.', $attribute)[1])]; + if (!isset($translation['language'])) { + // we can trust that another validator will fail this + return; + } + + if ($translation['language'] == 'en') { + if (is_null($this->formatId)) { + if ($value == 'VM' || $value == 'HY' || $value == 'TC') { + $fail(':attribute cannot be VM, HY, or TC for the english translation.'); + } + } else { + $existingFormat = $this->formatRepository->search(formatsInclude: [$this->formatId], langEnums: ['en'], showAll: true)->first(); + if (is_null($existingFormat)) { + if ($value == 'VM' || $value == 'HY' || $value == 'TC') { + $fail(':attribute cannot be VM, HY, or TC for the english translation.'); + } + } else { + if ($existingFormat->key_string == 'VM' && $value != 'VM') { + $fail(':attribute cannot be changed for the english VM format.'); + } elseif ($existingFormat->key_string == 'HY' && $value != 'HY') { + $fail(':attribute cannot be changed for the english HY format.'); + } elseif ($existingFormat->key_string == 'TC' && $value != 'TC') { + $fail(':attribute cannot be changed for the english TC format.'); + } + } + } + } + + $duplicates = $this->formatRepository->search( + formatsExclude: is_null($this->formatId) ? null : [$this->formatId], + langEnums: [$translation['language']], + keyStrings: [$value], + showAll: true + ); + if ($duplicates->isNotEmpty()) { + $fail(':attribute cannot be the same as another format\'s for the same language.'); + } + } + + public function setData(array $data): static + { + $this->data = $data; + return $this; + } +} diff --git a/src/app/Rules/FormatTranslations.php b/src/app/Rules/FormatTranslations.php new file mode 100644 index 000000000..93f4e679f --- /dev/null +++ b/src/app/Rules/FormatTranslations.php @@ -0,0 +1,39 @@ +formatRepository = $formatRepository; + $this->formatId = $formatId; + } + + public function validate(string $attribute, mixed $value, Closure $fail): void + { + if (is_null($this->formatId)) { + return; + } + + $virtualFormatId = $this->formatRepository->getVirtualFormat()->shared_id_bigint; + $hybridFormatId = $this->formatRepository->getHybridFormat()->shared_id_bigint; + $tempClosedFormatId = $this->formatRepository->getTemporarilyClosedFormat()->shared_id_bigint; + $reservedFormatIds = [$virtualFormatId, $hybridFormatId, $tempClosedFormatId]; + if (!in_array($this->formatId, $reservedFormatIds)) { + return; + } + + $translations = collect($value); + if ($translations->filter(fn ($t) => $t['language'] == 'en')->isEmpty()) { + $fail("the english translation of a reserved format cannot be deleted."); + } + } +} diff --git a/src/app/helpers.php b/src/app/helpers.php index bc0ee3674..6c2bc5b8d 100644 --- a/src/app/helpers.php +++ b/src/app/helpers.php @@ -1,11 +1,19 @@ =7.4", + "phpstan/phpdoc-parser": "^2.0", "psr/log": "^1.1 || ^2.0 || ^3.0", "symfony/deprecation-contracts": "^2 || ^3", "symfony/finder": "^5.0 || ^6.0 || ^7.0", - "symfony/yaml": "^5.0 || ^6.0 || ^7.0" + "symfony/yaml": "^5.4 || ^6.0 || ^7.0" }, "conflict": { "symfony/process": ">=6, <6.4.14" @@ -7015,7 +7070,8 @@ "vimeo/psalm": "^4.30 || ^5.0" }, "suggest": { - "doctrine/annotations": "^2.0" + "doctrine/annotations": "^2.0", + "radebatz/type-info-extras": "^1.0.2" }, "bin": [ "bin/openapi" @@ -7061,9 +7117,9 @@ ], "support": { "issues": "https://github.com/zircote/swagger-php/issues", - "source": "https://github.com/zircote/swagger-php/tree/5.3.0" + "source": "https://github.com/zircote/swagger-php/tree/5.7.0" }, - "time": "2025-08-14T23:31:27+00:00" + "time": "2025-11-11T03:41:35+00:00" } ], "packages-dev": [ @@ -7509,16 +7565,16 @@ }, { "name": "larastan/larastan", - "version": "v3.6.0", + "version": "v3.8.0", "source": { "type": "git", "url": "https://github.com/larastan/larastan.git", - "reference": "6431d010dd383a9279eb8874a76ddb571738564a" + "reference": "d13ef96d652d1b2a8f34f1760ba6bf5b9c98112e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/larastan/larastan/zipball/6431d010dd383a9279eb8874a76ddb571738564a", - "reference": "6431d010dd383a9279eb8874a76ddb571738564a", + "url": "https://api.github.com/repos/larastan/larastan/zipball/d13ef96d652d1b2a8f34f1760ba6bf5b9c98112e", + "reference": "d13ef96d652d1b2a8f34f1760ba6bf5b9c98112e", "shasum": "" }, "require": { @@ -7532,7 +7588,7 @@ "illuminate/pipeline": "^11.44.2 || ^12.4.1", "illuminate/support": "^11.44.2 || ^12.4.1", "php": "^8.2", - "phpstan/phpstan": "^2.1.11" + "phpstan/phpstan": "^2.1.29" }, "require-dev": { "doctrine/coding-standard": "^13", @@ -7545,7 +7601,8 @@ "phpunit/phpunit": "^10.5.35 || ^11.5.15" }, "suggest": { - "orchestra/testbench": "Using Larastan for analysing a package needs Testbench" + "orchestra/testbench": "Using Larastan for analysing a package needs Testbench", + "phpmyadmin/sql-parser": "Install to enable Larastan's optional phpMyAdmin-based SQL parser automatically" }, "type": "phpstan-extension", "extra": { @@ -7586,7 +7643,7 @@ ], "support": { "issues": "https://github.com/larastan/larastan/issues", - "source": "https://github.com/larastan/larastan/tree/v3.6.0" + "source": "https://github.com/larastan/larastan/tree/v3.8.0" }, "funding": [ { @@ -7594,20 +7651,20 @@ "type": "github" } ], - "time": "2025-07-11T06:52:52+00:00" + "time": "2025-10-27T23:09:14+00:00" }, { "name": "laravel/pint", - "version": "v1.24.0", + "version": "v1.25.1", "source": { "type": "git", "url": "https://github.com/laravel/pint.git", - "reference": "0345f3b05f136801af8c339f9d16ef29e6b4df8a" + "reference": "5016e263f95d97670d71b9a987bd8996ade6d8d9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/pint/zipball/0345f3b05f136801af8c339f9d16ef29e6b4df8a", - "reference": "0345f3b05f136801af8c339f9d16ef29e6b4df8a", + "url": "https://api.github.com/repos/laravel/pint/zipball/5016e263f95d97670d71b9a987bd8996ade6d8d9", + "reference": "5016e263f95d97670d71b9a987bd8996ade6d8d9", "shasum": "" }, "require": { @@ -7618,9 +7675,9 @@ "php": "^8.2.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^3.82.2", - "illuminate/view": "^11.45.1", - "larastan/larastan": "^3.5.0", + "friendsofphp/php-cs-fixer": "^3.87.2", + "illuminate/view": "^11.46.0", + "larastan/larastan": "^3.7.1", "laravel-zero/framework": "^11.45.0", "mockery/mockery": "^1.6.12", "nunomaduro/termwind": "^2.3.1", @@ -7631,9 +7688,6 @@ ], "type": "project", "autoload": { - "files": [ - "overrides/Runner/Parallel/ProcessFactory.php" - ], "psr-4": { "App\\": "app/", "Database\\Seeders\\": "database/seeders/", @@ -7663,20 +7717,20 @@ "issues": "https://github.com/laravel/pint/issues", "source": "https://github.com/laravel/pint" }, - "time": "2025-07-10T18:09:32+00:00" + "time": "2025-09-19T02:57:12+00:00" }, { "name": "laravel/sail", - "version": "v1.44.0", + "version": "v1.48.0", "source": { "type": "git", "url": "https://github.com/laravel/sail.git", - "reference": "a09097bd2a8a38e23ac472fa6a6cf5b0d1c1d3fe" + "reference": "1bf3b8870b72a258a3b6b5119435835ece522e8a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/sail/zipball/a09097bd2a8a38e23ac472fa6a6cf5b0d1c1d3fe", - "reference": "a09097bd2a8a38e23ac472fa6a6cf5b0d1c1d3fe", + "url": "https://api.github.com/repos/laravel/sail/zipball/1bf3b8870b72a258a3b6b5119435835ece522e8a", + "reference": "1bf3b8870b72a258a3b6b5119435835ece522e8a", "shasum": "" }, "require": { @@ -7689,7 +7743,7 @@ }, "require-dev": { "orchestra/testbench": "^7.0|^8.0|^9.0|^10.0", - "phpstan/phpstan": "^1.10" + "phpstan/phpstan": "^2.0" }, "bin": [ "bin/sail" @@ -7726,20 +7780,20 @@ "issues": "https://github.com/laravel/sail/issues", "source": "https://github.com/laravel/sail" }, - "time": "2025-07-04T16:17:06+00:00" + "time": "2025-11-09T14:46:21+00:00" }, { "name": "league/csv", - "version": "9.24.1", + "version": "9.27.1", "source": { "type": "git", "url": "https://github.com/thephpleague/csv.git", - "reference": "e0221a3f16aa2a823047d59fab5809d552e29bc8" + "reference": "26de738b8fccf785397d05ee2fc07b6cd8749797" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/csv/zipball/e0221a3f16aa2a823047d59fab5809d552e29bc8", - "reference": "e0221a3f16aa2a823047d59fab5809d552e29bc8", + "url": "https://api.github.com/repos/thephpleague/csv/zipball/26de738b8fccf785397d05ee2fc07b6cd8749797", + "reference": "26de738b8fccf785397d05ee2fc07b6cd8749797", "shasum": "" }, "require": { @@ -7755,7 +7809,7 @@ "phpstan/phpstan-deprecation-rules": "^1.2.1", "phpstan/phpstan-phpunit": "^1.4.2", "phpstan/phpstan-strict-rules": "^1.6.2", - "phpunit/phpunit": "^10.5.16 || ^11.5.22", + "phpunit/phpunit": "^10.5.16 || ^11.5.22 || ^12.3.6", "symfony/var-dumper": "^6.4.8 || ^7.3.0" }, "suggest": { @@ -7817,7 +7871,7 @@ "type": "github" } ], - "time": "2025-06-25T14:53:51+00:00" + "time": "2025-10-25T08:35:20+00:00" }, { "name": "mockery/mockery", @@ -8181,16 +8235,11 @@ }, { "name": "phpstan/phpstan", - "version": "2.1.22", - "source": { - "type": "git", - "url": "https://github.com/phpstan/phpstan.git", - "reference": "41600c8379eb5aee63e9413fe9e97273e25d57e4" - }, + "version": "2.1.32", "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/41600c8379eb5aee63e9413fe9e97273e25d57e4", - "reference": "41600c8379eb5aee63e9413fe9e97273e25d57e4", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/e126cad1e30a99b137b8ed75a85a676450ebb227", + "reference": "e126cad1e30a99b137b8ed75a85a676450ebb227", "shasum": "" }, "require": { @@ -8235,20 +8284,20 @@ "type": "github" } ], - "time": "2025-08-04T19:17:37+00:00" + "time": "2025-11-11T15:18:17+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "11.0.10", + "version": "11.0.11", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "1a800a7446add2d79cc6b3c01c45381810367d76" + "reference": "4f7722aa9a7b76aa775e2d9d4e95d1ea16eeeef4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/1a800a7446add2d79cc6b3c01c45381810367d76", - "reference": "1a800a7446add2d79cc6b3c01c45381810367d76", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/4f7722aa9a7b76aa775e2d9d4e95d1ea16eeeef4", + "reference": "4f7722aa9a7b76aa775e2d9d4e95d1ea16eeeef4", "shasum": "" }, "require": { @@ -8305,7 +8354,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/show" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/11.0.11" }, "funding": [ { @@ -8325,7 +8374,7 @@ "type": "tidelift" } ], - "time": "2025-06-18T08:56:18+00:00" + "time": "2025-08-27T14:37:49+00:00" }, { "name": "phpunit/php-file-iterator", @@ -8574,16 +8623,16 @@ }, { "name": "phpunit/phpunit", - "version": "11.5.33", + "version": "11.5.44", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "5965e9ff57546cb9137c0ff6aa78cb7442b05cf6" + "reference": "c346885c95423eda3f65d85a194aaa24873cda82" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/5965e9ff57546cb9137c0ff6aa78cb7442b05cf6", - "reference": "5965e9ff57546cb9137c0ff6aa78cb7442b05cf6", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c346885c95423eda3f65d85a194aaa24873cda82", + "reference": "c346885c95423eda3f65d85a194aaa24873cda82", "shasum": "" }, "require": { @@ -8597,7 +8646,7 @@ "phar-io/manifest": "^2.0.4", "phar-io/version": "^3.2.1", "php": ">=8.2", - "phpunit/php-code-coverage": "^11.0.10", + "phpunit/php-code-coverage": "^11.0.11", "phpunit/php-file-iterator": "^5.1.0", "phpunit/php-invoker": "^5.0.1", "phpunit/php-text-template": "^4.0.1", @@ -8607,7 +8656,7 @@ "sebastian/comparator": "^6.3.2", "sebastian/diff": "^6.0.2", "sebastian/environment": "^7.2.1", - "sebastian/exporter": "^6.3.0", + "sebastian/exporter": "^6.3.2", "sebastian/global-state": "^7.0.2", "sebastian/object-enumerator": "^6.0.1", "sebastian/type": "^5.1.3", @@ -8655,7 +8704,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/11.5.33" + "source": "https://github.com/sebastianbergmann/phpunit/tree/11.5.44" }, "funding": [ { @@ -8679,7 +8728,7 @@ "type": "tidelift" } ], - "time": "2025-08-16T05:19:02+00:00" + "time": "2025-11-13T07:17:35+00:00" }, { "name": "sebastian/cli-parser", @@ -9146,16 +9195,16 @@ }, { "name": "sebastian/exporter", - "version": "6.3.0", + "version": "6.3.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "3473f61172093b2da7de1fb5782e1f24cc036dc3" + "reference": "70a298763b40b213ec087c51c739efcaa90bcd74" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/3473f61172093b2da7de1fb5782e1f24cc036dc3", - "reference": "3473f61172093b2da7de1fb5782e1f24cc036dc3", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/70a298763b40b213ec087c51c739efcaa90bcd74", + "reference": "70a298763b40b213ec087c51c739efcaa90bcd74", "shasum": "" }, "require": { @@ -9169,7 +9218,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "6.1-dev" + "dev-main": "6.3-dev" } }, "autoload": { @@ -9212,15 +9261,27 @@ "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", "security": "https://github.com/sebastianbergmann/exporter/security/policy", - "source": "https://github.com/sebastianbergmann/exporter/tree/6.3.0" + "source": "https://github.com/sebastianbergmann/exporter/tree/6.3.2" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/exporter", + "type": "tidelift" } ], - "time": "2024-12-05T09:17:50+00:00" + "time": "2025-09-24T06:12:51+00:00" }, { "name": "sebastian/global-state", @@ -9657,16 +9718,16 @@ }, { "name": "spatie/backtrace", - "version": "1.7.4", + "version": "1.8.1", "source": { "type": "git", "url": "https://github.com/spatie/backtrace.git", - "reference": "cd37a49fce7137359ac30ecc44ef3e16404cccbe" + "reference": "8c0f16a59ae35ec8c62d85c3c17585158f430110" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/backtrace/zipball/cd37a49fce7137359ac30ecc44ef3e16404cccbe", - "reference": "cd37a49fce7137359ac30ecc44ef3e16404cccbe", + "url": "https://api.github.com/repos/spatie/backtrace/zipball/8c0f16a59ae35ec8c62d85c3c17585158f430110", + "reference": "8c0f16a59ae35ec8c62d85c3c17585158f430110", "shasum": "" }, "require": { @@ -9704,7 +9765,8 @@ "spatie" ], "support": { - "source": "https://github.com/spatie/backtrace/tree/1.7.4" + "issues": "https://github.com/spatie/backtrace/issues", + "source": "https://github.com/spatie/backtrace/tree/1.8.1" }, "funding": [ { @@ -9716,7 +9778,7 @@ "type": "other" } ], - "time": "2025-05-08T15:41:09+00:00" + "time": "2025-08-26T08:22:30+00:00" }, { "name": "spatie/error-solutions", @@ -10037,16 +10099,16 @@ }, { "name": "squizlabs/php_codesniffer", - "version": "3.13.2", + "version": "3.13.5", "source": { "type": "git", "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git", - "reference": "5b5e3821314f947dd040c70f7992a64eac89025c" + "reference": "0ca86845ce43291e8f5692c7356fccf3bcf02bf4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/5b5e3821314f947dd040c70f7992a64eac89025c", - "reference": "5b5e3821314f947dd040c70f7992a64eac89025c", + "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/0ca86845ce43291e8f5692c7356fccf3bcf02bf4", + "reference": "0ca86845ce43291e8f5692c7356fccf3bcf02bf4", "shasum": "" }, "require": { @@ -10063,11 +10125,6 @@ "bin/phpcs" ], "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.x-dev" - } - }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" @@ -10117,7 +10174,7 @@ "type": "thanks_dev" } ], - "time": "2025-06-17T22:17:01+00:00" + "time": "2025-11-04T16:30:35+00:00" }, { "name": "staabm/side-effects-detector", diff --git a/src/config/aggregator.php b/src/config/aggregator.php index 8ad900296..558fc3160 100644 --- a/src/config/aggregator.php +++ b/src/config/aggregator.php @@ -3,13 +3,13 @@ return [ 'ignore_root_servers' => json_decode(env('AGGREGATOR_IGNORE_ROOT_SERVERS') ?? 'null') ?? [], 'ignore_service_bodies' => json_decode(env('AGGREGATOR_IGNORE_SERVICE_BODIES') ?? 'null') ?? [ - 120 => [ # {"id":"120","name":"NA New Jersey","rootURL":"https://www.narcoticsanonymousnj.org/main_server/"} + 120 => [ # {"id":"120","name":"NA New Jersey","url":"https://www.narcoticsanonymousnj.org/main_server/"} 31, 32, # Duplicated Eastern New York Region 27, 28 # Duplicated Greater Philadelphia Region ], ], 'rate_limit_root_servers' => json_decode(env('AGGREGATOR_RATE_LIMIT_ROOT_SERVERS') ?? 'null') ?? [ - # {"id":"139","name":"NA Argentina","rootURL":"https://www.na.org.ar/main_server/"}, + # {"id":"139","name":"NA Argentina","url":"https://www.na.org.ar/main_server/"}, 139 => ['request_delay' => 10, 'retry_delay' => 300], ], ]; diff --git a/src/config/app.php b/src/config/app.php index 055a7c8f5..2085482a1 100644 --- a/src/config/app.php +++ b/src/config/app.php @@ -15,7 +15,7 @@ | */ - 'name' => env('APP_NAME', 'BMLT Root Server'), + 'name' => env('APP_NAME', 'BMLT Server'), /* @@ -28,7 +28,7 @@ | or any other location as required by the application or its packages. */ - 'version' => env('APP_VERSION', '4.0.0'), + 'version' => env('APP_VERSION', '4.1.0'), /* |-------------------------------------------------------------------------- @@ -106,7 +106,10 @@ | */ - 'locale' => legacy_config('language', 'en'), + // Note: Cannot load from database because config files are loaded before DB connection. + // This is just a fallback, actual language comes from setting in database. + // Note that language specific translations for things like server error messages probably wont work. + 'locale' => 'en', /* |-------------------------------------------------------------------------- diff --git a/src/config/broadcasting.php b/src/config/broadcasting.php index 168824244..3fe737e3e 100644 --- a/src/config/broadcasting.php +++ b/src/config/broadcasting.php @@ -36,7 +36,7 @@ 'secret' => env('PUSHER_APP_SECRET'), 'app_id' => env('PUSHER_APP_ID'), 'options' => [ - 'host' => env('PUSHER_HOST', 'api-'.env('PUSHER_APP_CLUSTER', 'mt1').'.pusher.com') ?: 'api-'.env('PUSHER_APP_CLUSTER', 'mt1').'.pusher.com', + 'host' => env('PUSHER_HOST', 'api-' . env('PUSHER_APP_CLUSTER', 'mt1') . '.pusher.com') ?: 'api-' . env('PUSHER_APP_CLUSTER', 'mt1') . '.pusher.com', 'port' => env('PUSHER_PORT', 443), 'scheme' => env('PUSHER_SCHEME', 'https'), 'encrypted' => true, diff --git a/src/config/cache.php b/src/config/cache.php index 33bb29546..daf5e68be 100644 --- a/src/config/cache.php +++ b/src/config/cache.php @@ -105,6 +105,6 @@ | */ - 'prefix' => env('CACHE_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_cache_'), + 'prefix' => env('CACHE_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_') . '_cache_'), ]; diff --git a/src/config/database.php b/src/config/database.php index 26ce537b2..92f3c16c7 100644 --- a/src/config/database.php +++ b/src/config/database.php @@ -2,6 +2,13 @@ use Illuminate\Support\Str; +$dbPrefix = file_config('db_prefix', ''); +if ($dbPrefix) { + $dbPrefix = $dbPrefix . '_'; +} elseif (env('APP_ENV') === 'testing') { + $dbPrefix = 'test_'; +} + return [ /* @@ -38,15 +45,15 @@ 'mysql' => [ 'driver' => 'mysql', 'url' => env('DATABASE_URL'), - 'host' => legacy_config('db_host', '0.0.0.0'), + 'host' => file_config('db_host', '0.0.0.0'), 'port' => env('DB_PORT', '3306'), - 'database' => legacy_config('db_database'), - 'username' => legacy_config('db_username'), - 'password' => legacy_config('db_password'), + 'database' => file_config('db_database'), + 'username' => file_config('db_username'), + 'password' => file_config('db_password'), 'unix_socket' => env('DB_SOCKET', ''), 'charset' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci', - 'prefix' => legacy_config('db_prefix') ? legacy_config('db_prefix') . '_' : 'test_', + 'prefix' => $dbPrefix, 'prefix_indexes' => true, 'strict' => true, 'engine' => 'InnoDB', @@ -58,15 +65,15 @@ 'test' => [ 'driver' => 'mysql', 'url' => env('DATABASE_URL'), - 'host' => legacy_config('db_host', '0.0.0.0'), + 'host' => file_config('db_host', '0.0.0.0'), 'port' => env('DB_PORT', '3306'), - 'database' => legacy_config('db_database', 'rootserver'), - 'username' => legacy_config('db_username', 'root'), - 'password' => legacy_config('db_password', 'rootserver'), + 'database' => file_config('db_database', 'rootserver'), + 'username' => file_config('db_username', 'root'), + 'password' => file_config('db_password', 'rootserver'), 'unix_socket' => env('DB_SOCKET', ''), 'charset' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci', - 'prefix' => legacy_config('db_prefix') ? legacy_config('db_prefix') . '_' : 'test_', + 'prefix' => $dbPrefix, 'prefix_indexes' => true, 'strict' => true, 'engine' => 'InnoDB', @@ -106,7 +113,7 @@ 'options' => [ 'cluster' => env('REDIS_CLUSTER', 'redis'), - 'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'), + 'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_') . '_database_'), ], 'default' => [ diff --git a/src/config/filesystems.php b/src/config/filesystems.php index fefc24464..6b55fbe23 100644 --- a/src/config/filesystems.php +++ b/src/config/filesystems.php @@ -45,7 +45,7 @@ 'public' => [ 'driver' => 'local', 'root' => storage_path('app/public'), - 'url' => env('APP_URL').'/storage', + 'url' => env('APP_URL') . '/storage', 'visibility' => 'public', 'throw' => false, ], diff --git a/src/config/logging.php b/src/config/logging.php index 5aa1dbb78..752af7110 100644 --- a/src/config/logging.php +++ b/src/config/logging.php @@ -85,7 +85,7 @@ 'handler_with' => [ 'host' => env('PAPERTRAIL_URL'), 'port' => env('PAPERTRAIL_PORT'), - 'connectionString' => 'tls://'.env('PAPERTRAIL_URL').':'.env('PAPERTRAIL_PORT'), + 'connectionString' => 'tls://' . env('PAPERTRAIL_URL') . ':' . env('PAPERTRAIL_PORT'), ], ], diff --git a/src/config/session.php b/src/config/session.php index 749008183..b271aa8a5 100644 --- a/src/config/session.php +++ b/src/config/session.php @@ -128,7 +128,7 @@ 'cookie' => env( 'SESSION_COOKIE', - Str::slug(env('APP_NAME', 'laravel'), '_').'_session' + Str::slug(env('APP_NAME', 'laravel'), '_') . '_session' ), /* diff --git a/src/database/migrations/1901_01_01_000000_legacy_migrations.php b/src/database/migrations/1901_01_01_000000_legacy_migrations.php index 98a06450d..824ee4f5a 100644 --- a/src/database/migrations/1901_01_01_000000_legacy_migrations.php +++ b/src/database/migrations/1901_01_01_000000_legacy_migrations.php @@ -25,8 +25,6 @@ public function up() $dbName = config('database.connections.mysql.database'); $dbPrefix = rtrim(config('database.connections.mysql.prefix'), '_'); - require_once(__DIR__."/../../legacy/server/shared/classes/VenueType.php"); - // Make sure version table exists $versionTableName = $dbPrefix . "_comdef_db_version"; $sql = "SELECT COUNT(*) as count FROM information_schema.tables WHERE TABLE_SCHEMA = '$dbName' AND TABLE_NAME = '$versionTableName'"; @@ -459,9 +457,9 @@ function getFormatStrFilter($formatId, $hasFormat) return $filter . ")"; } - $VENUE_TYPE_HYBRID = VenueType::HYBRID; - $VENUE_TYPE_VIRTUAL = VenueType::VIRTUAL; - $VENUE_TYPE_IN_PERSON = VenueType::IN_PERSON; + $VENUE_TYPE_HYBRID = 3; + $VENUE_TYPE_VIRTUAL = 2; + $VENUE_TYPE_IN_PERSON = 1; $vmFormatId = getFormatId($this, "VM"); $hyFormatId = getFormatId($this, "HY"); $tcFormatId = getFormatId($this, "TC"); diff --git a/src/database/migrations/1902_01_01_000000_create_initial_schema.php b/src/database/migrations/1902_01_01_000000_create_initial_schema.php index 658bcbd91..17876c283 100644 --- a/src/database/migrations/1902_01_01_000000_create_initial_schema.php +++ b/src/database/migrations/1902_01_01_000000_create_initial_schema.php @@ -182,7 +182,7 @@ public function up() $table->index('key_string', 'key_string'); $table->index(['root_server_id', 'source_id'], 'root_server_id_source_id'); }); - if (!legacy_config('aggregator_mode_enabled')) { + if (!file_config('aggregator_mode_enabled')) { // aggregator mode does not need any stock data DB::table('comdef_formats')->insert([ ['shared_id_bigint' => 1, 'key_string' => 'B', 'worldid_mixed' => 'BEG', 'lang_enum' => 'de', 'name_string' => 'Beginners', 'description_string' => 'This meeting is focused on the needs of new members of NA.', 'format_type_enum' => 'FC3'], @@ -456,7 +456,7 @@ public function up() ['shared_id_bigint' => 35, 'key_string' => 'M', 'worldid_mixed' => null, 'lang_enum' => 'it', 'name_string' => 'Maratona', 'description_string' => 'Durata non prestabilita. La riunione prosegue finché tutti i presenti hanno da condividere.', 'format_type_enum' => 'FC1'], ['shared_id_bigint' => 37, 'key_string' => 'NF', 'worldid_mixed' => null, 'lang_enum' => 'it', 'name_string' => 'Non fumatori', 'description_string' => 'In queste riunioni non è consentito fumare.', 'format_type_enum' => 'FC1'], ['shared_id_bigint' => 40, 'key_string' => 'TS', 'worldid_mixed' => null, 'lang_enum' => 'it', 'name_string' => 'Tema a sorpresa', 'description_string' => 'L\'argomento su cui condividere è scritto su un biglietto o altro supporto (es. un bastoncino di legno) ed estratto a caso da ciascun membro.', 'format_type_enum' => 'FC1'], - ['shared_id_bigint' => 42, 'key_string' => 'M', 'worldid_mixed' => null, 'lang_enum' => 'it', 'name_string' => 'Meditazione', 'description_string' => 'In questa riunione sono poste restrizioni alle modalità di partecipazione.', 'format_type_enum' => 'FC3'], + ['shared_id_bigint' => 42, 'key_string' => 'AR', 'worldid_mixed' => null, 'lang_enum' => 'it', 'name_string' => 'Accesso ristretto', 'description_string' => 'In questa riunione sono poste restrizioni alle modalità di partecipazione.', 'format_type_enum' => 'FC3'], ['shared_id_bigint' => 43, 'key_string' => 'D/R', 'worldid_mixed' => null, 'lang_enum' => 'it', 'name_string' => 'Domande e risposteq', 'description_string' => 'I partecipanti possono fare domande e attenderne la risposta dagli altri membri del gruppo.', 'format_type_enum' => 'FC1'], ['shared_id_bigint' => 44, 'key_string' => 'Ba', 'worldid_mixed' => null, 'lang_enum' => 'it', 'name_string' => 'Bambini', 'description_string' => 'I bambini sono benvenuti in queste riunioni.', 'format_type_enum' => 'FC3'], ['shared_id_bigint' => 45, 'key_string' => 'C', 'worldid_mixed' => null, 'lang_enum' => 'it', 'name_string' => 'Concetti di servizio', 'description_string' => 'Riunioni basate sulla discussione dei Dodici concetti per il servizio in NA.', 'format_type_enum' => 'FC1'], @@ -522,7 +522,7 @@ public function up() ['shared_id_bigint' => 3, 'key_string' => 'TB', 'worldid_mixed' => 'BT', 'lang_enum' => 'pt', 'name_string' => 'Texto Básico', 'description_string' => 'Esta reunião tem foco no debate sobre o Texto Básico de Narcóticos Anônimos.', 'format_type_enum' => 'FC1'], ['shared_id_bigint' => 4, 'key_string' => 'F', 'worldid_mixed' => 'CLOSED', 'lang_enum' => 'pt', 'name_string' => 'Fechada', 'description_string' => 'Esta reunião fechada para não adictos. Você deve ir apenas se acredita ter problemas com abuso de substâncias.', 'format_type_enum' => 'O'], ['shared_id_bigint' => 5, 'key_string' => 'FF', 'worldid_mixed' => 'CH', 'lang_enum' => 'pt', 'name_string' => 'Fechada em feriados', 'description_string' => 'Esta reunião acontece em local que geralmente é fechado em feirados.', 'format_type_enum' => 'FC3'], - ['shared_id_bigint' => 6, 'key_string' => 'VL', 'worldid_mixed' => 'CAN', 'lang_enum' => 'pt', 'name_string' => 'Luz de velas', 'description_string' => 'Esta reunião acontece à luz de velas.', 'format_type_enum' => 'FC2'], + ['shared_id_bigint' => 6, 'key_string' => 'LV', 'worldid_mixed' => 'CAN', 'lang_enum' => 'pt', 'name_string' => 'Luz de velas', 'description_string' => 'Esta reunião acontece à luz de velas.', 'format_type_enum' => 'FC2'], ['shared_id_bigint' => 7, 'key_string' => 'CA', 'worldid_mixed' => '', 'lang_enum' => 'pt', 'name_string' => 'Criança sob supervisão', 'description_string' => 'Bem-comportadas, crianças sob supervisão são bem-vindas.', 'format_type_enum' => 'FC3'], ['shared_id_bigint' => 8, 'key_string' => 'D', 'worldid_mixed' => 'DISC', 'lang_enum' => 'pt', 'name_string' => 'Discussão', 'description_string' => 'Esta reunião convida a participação de todos.', 'format_type_enum' => 'FC1'], ['shared_id_bigint' => 9, 'key_string' => 'ES', 'worldid_mixed' => 'LANG', 'lang_enum' => 'pt', 'name_string' => 'Espanhol', 'description_string' => 'Esta reunião acontece em Espanhol.', 'format_type_enum' => 'LANG'], @@ -559,7 +559,7 @@ public function up() ['shared_id_bigint' => 41, 'key_string' => 'ME', 'worldid_mixed' => 'MED', 'lang_enum' => 'pt', 'name_string' => 'Meditação', 'description_string' => 'Esta reunião incentiva seus participantes a se envolverem em meditação silenciosa.', 'format_type_enum' => 'FC1'], ['shared_id_bigint' => 42, 'key_string' => 'AR', 'worldid_mixed' => 'RA', 'lang_enum' => 'pt', 'name_string' => 'Acesso Restrito', 'description_string' => 'Esta reunião esta em local que impõe restrição de acesso às pessoas.', 'format_type_enum' => 'FC3'], ['shared_id_bigint' => 43, 'key_string' => 'PR', 'worldid_mixed' => 'QA', 'lang_enum' => 'pt', 'name_string' => 'Perguntas e Respostas', 'description_string' => 'Os participantes podem fazer perguntas e esperar respostas dos membros do grupo.', 'format_type_enum' => 'FC1'], - ['shared_id_bigint' => 44, 'key_string' => 'PC', 'worldid_mixed' => 'CW', 'lang_enum' => 'pt', 'name_string' => 'Permitido Crianças', 'description_string' => 'Crianças são bem-vindas a essa reunião.', 'format_type_enum' => 'FC3'], + ['shared_id_bigint' => 44, 'key_string' => 'CBV', 'worldid_mixed' => 'CW', 'lang_enum' => 'pt', 'name_string' => 'Crianças são bem-vindas', 'description_string' => 'Crianças são bem-vindas a essa reunião.', 'format_type_enum' => 'FC3'], ['shared_id_bigint' => 45, 'key_string' => 'Con', 'worldid_mixed' => 'CPT', 'lang_enum' => 'pt', 'name_string' => 'Conceitos', 'description_string' => 'Esta reunião tem foco na discussão dos Doze Conceitos de NA.', 'format_type_enum' => 'FC1'], ['shared_id_bigint' => 46, 'key_string' => 'FIN', 'worldid_mixed' => 'LANG', 'lang_enum' => 'pt', 'name_string' => 'Filandês', 'description_string' => 'Reunião em língua filandesa', 'format_type_enum' => 'LANG'], ['shared_id_bigint' => 47, 'key_string' => 'ENG', 'worldid_mixed' => 'LANG', 'lang_enum' => 'pt', 'name_string' => 'Inglês', 'description_string' => 'Reunião em língua inglesa.', 'format_type_enum' => 'LANG'], @@ -630,7 +630,6 @@ public function up() ['shared_id_bigint' => 48, 'key_string' => 'PER', 'worldid_mixed' => null, 'lang_enum' => 'sv', 'name_string' => 'Persiskt', 'description_string' => 'Persiskt möte', 'format_type_enum' => 'FC1'], ['shared_id_bigint' => 32, 'key_string' => 'K', 'worldid_mixed' => 'W', 'lang_enum' => 'sv', 'name_string' => 'Kvinnomöte', 'description_string' => 'Detta möte är endast öppet för kvinnor.', 'format_type_enum' => 'FC3'], ['shared_id_bigint' => 33, 'key_string' => 'RL', 'worldid_mixed' => 'WCHR', 'lang_enum' => 'sv', 'name_string' => 'Rullstolsvänlig lokal', 'description_string' => 'Detta möte är tillgängligt för rullstolsbundna.', 'format_type_enum' => 'FC2'], - ['shared_id_bigint' => 47, 'key_string' => 'ENG', 'worldid_mixed' => null, 'lang_enum' => 'sv', 'name_string' => 'Engelska', 'description_string' => 'Engelsktalande möte', 'format_type_enum' => 'FC3'], ['shared_id_bigint' => 54, 'key_string' => 'VM', 'worldid_mixed' => 'VM', 'lang_enum' => 'sv', 'name_string' => 'Virtual Meeting', 'description_string' => 'Meets Virtually', 'format_type_enum' => 'FC2'], ['shared_id_bigint' => 55, 'key_string' => 'TC', 'worldid_mixed' => 'TC', 'lang_enum' => 'sv', 'name_string' => 'Temporarily Closed Facility', 'description_string' => 'Facility is Temporarily Closed', 'format_type_enum' => 'FC2'], ['shared_id_bigint' => 56, 'key_string' => 'HY', 'worldid_mixed' => 'HYBR', 'lang_enum' => 'sv', 'name_string' => 'Hybrid Meeting', 'description_string' => 'Meets Virtually and In-person', 'format_type_enum' => 'FC2'], diff --git a/src/database/migrations/2023_05_16_223943_format_types.php b/src/database/migrations/2023_05_16_223943_format_types.php index f2afa46f4..4bb0f0f58 100644 --- a/src/database/migrations/2023_05_16_223943_format_types.php +++ b/src/database/migrations/2023_05_16_223943_format_types.php @@ -26,7 +26,7 @@ public function up() $table->index('key_string'); $table->index('api_enum'); }); - if (!legacy_config('aggregator_mode_enabled')) { + if (!file_config('aggregator_mode_enabled')) { // aggregator mode does not need any stock data DB::table('comdef_format_types')->insert([ ['key_string' => 'FC1', 'api_enum' => 'MEETING_FORMAT', 'position_int' => '1'], diff --git a/src/database/migrations/2024_06_12_164303_fix_meeting_lang_enum.php b/src/database/migrations/2024_06_12_164303_fix_meeting_lang_enum.php index ab90968bd..d6ffc4bd2 100644 --- a/src/database/migrations/2024_06_12_164303_fix_meeting_lang_enum.php +++ b/src/database/migrations/2024_06_12_164303_fix_meeting_lang_enum.php @@ -12,7 +12,7 @@ */ public function up() { - if (!legacy_config('aggregator_mode_enabled')) { + if (!file_config('aggregator_mode_enabled')) { DB::table('comdef_meetings_main') ->whereNull('lang_enum') ->update(['lang_enum' => config('app.locale')]); diff --git a/src/database/migrations/2024_07_20_203802_fix_admin_user_owners.php b/src/database/migrations/2024_07_20_203802_fix_admin_user_owners.php index cb7a2bda9..3c0b0a882 100644 --- a/src/database/migrations/2024_07_20_203802_fix_admin_user_owners.php +++ b/src/database/migrations/2024_07_20_203802_fix_admin_user_owners.php @@ -10,7 +10,7 @@ */ public function up(): void { - if (!legacy_config('aggregator_mode_enabled')) { + if (!file_config('aggregator_mode_enabled')) { $adminUserIds = DB::table('comdef_users')->where('user_level_tinyint', 1)->pluck('id_bigint'); DB::table('comdef_users')->whereIn('owner_id_bigint', $adminUserIds)->update(['owner_id_bigint' => -1]); } diff --git a/src/database/migrations/2025_09_25_123352_set_langenum_to_app_locale.php b/src/database/migrations/2025_09_25_123352_set_langenum_to_app_locale.php new file mode 100644 index 000000000..73b96d336 --- /dev/null +++ b/src/database/migrations/2025_09_25_123352_set_langenum_to_app_locale.php @@ -0,0 +1,26 @@ +update(['lang_enum' => config('app.locale')]); + Schema::table('comdef_users', function ($table) { + $table->string('target_language', 10)->nullable(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + } +}; diff --git a/src/database/migrations/2025_10_09_160510_add_serveradmin_if_needed.php b/src/database/migrations/2025_10_09_160510_add_serveradmin_if_needed.php new file mode 100644 index 000000000..4b7fcab31 --- /dev/null +++ b/src/database/migrations/2025_10_09_160510_add_serveradmin_if_needed.php @@ -0,0 +1,36 @@ +where('user_level_tinyint', 1)->count(); + if ($n == 0) { + DB::table('comdef_users')->insert([ + 'user_level_tinyint' => 1, + 'name_string' => 'Server Administrator', + 'description_string' => 'Main Server Administrator', + 'email_address_string' => '', + 'login_string' => 'serveradmin', + 'password_string' => Hash::make('change-this-password-first-thing') + ]); + }; + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + // + } +}; diff --git a/src/database/migrations/2025_11_10_014000_remove_nonexistent_assigned_users_from_service_bodies.php b/src/database/migrations/2025_11_10_014000_remove_nonexistent_assigned_users_from_service_bodies.php new file mode 100644 index 000000000..e46c49f82 --- /dev/null +++ b/src/database/migrations/2025_11_10_014000_remove_nonexistent_assigned_users_from_service_bodies.php @@ -0,0 +1,58 @@ +pluck('id_bigint'); + $serviceBodies = DB::table('comdef_service_bodies') + ->whereNotNull('editors_string') + ->whereNot('editors_string', '') + ->get(['id_bigint', 'editors_string']); + + foreach ($serviceBodies as $serviceBody) { + $oldUserIds = collect(explode(',', trim($serviceBody->editors_string))) + ->map(fn($userId) => trim($userId)) + ->filter(fn($userId) => !empty($userId) && is_numeric($userId)) + ->map(fn($userId) => intval($userId)); + + $newUserIds = $oldUserIds->filter(fn($userId) => $allUserIds->contains($userId)); + if ($oldUserIds->count() == $newUserIds->count()) { + continue; + } + + DB::table('comdef_service_bodies') + ->where('id_bigint', $serviceBody->id_bigint) + ->update(['editors_string' => $newUserIds->isEmpty() ? null : $newUserIds->implode(',')]); + + Log::info('Removed non-existent assigned users from service body', [ + 'service_body_id' => $serviceBody->id_bigint, + 'old_editors_string' => $serviceBody->editors_string, + 'new_editors_string' => $newUserIds->isEmpty() ? null : $newUserIds->implode(','), + 'removed_count' => $oldUserIds->count() - $newUserIds->count() + ]); + } + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + // + } +}; diff --git a/src/database/migrations/2025_11_11_174719_trim_user_whitespace.php b/src/database/migrations/2025_11_11_174719_trim_user_whitespace.php new file mode 100644 index 000000000..e8ffaa065 --- /dev/null +++ b/src/database/migrations/2025_11_11_174719_trim_user_whitespace.php @@ -0,0 +1,40 @@ +whereNotNull('name_string') + ->update(['name_string' => DB::raw('TRIM(name_string)')]); + + DB::table('comdef_users') + ->whereNotNull('description_string') + ->update(['description_string' => DB::raw('TRIM(description_string)')]); + + DB::table('comdef_users') + ->whereNotNull('login_string') + ->update(['login_string' => DB::raw('TRIM(login_string)')]); + + DB::table('comdef_users') + ->whereNotNull('email_address_string') + ->update(['email_address_string' => DB::raw('TRIM(email_address_string)')]); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + } +}; diff --git a/src/database/migrations/2025_11_20_133700_create_settings_table.php b/src/database/migrations/2025_11_20_133700_create_settings_table.php new file mode 100644 index 000000000..03714662b --- /dev/null +++ b/src/database/migrations/2025_11_20_133700_create_settings_table.php @@ -0,0 +1,34 @@ +bigIncrements('id'); + $table->string('name', 255)->unique(); + $table->string('type', 50)->default('string'); + $table->text('value')->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('settings'); + } +}; diff --git a/src/database/migrations/2025_11_20_133800_seed_settings_from_legacy_config.php b/src/database/migrations/2025_11_20_133800_seed_settings_from_legacy_config.php new file mode 100644 index 000000000..370483a85 --- /dev/null +++ b/src/database/migrations/2025_11_20_133800_seed_settings_from_legacy_config.php @@ -0,0 +1,154 @@ + self::TYPE_STRING, + 'changeDepthForMeetings' => self::TYPE_INT, + 'defaultSortKey' => self::TYPE_STRING, + 'language' => self::TYPE_STRING, + 'defaultDurationTime' => self::TYPE_STRING, + 'regionBias' => self::TYPE_STRING, + 'distanceUnits' => self::TYPE_STRING, + 'meetingStatesAndProvinces' => self::TYPE_ARRAY, + 'meetingCountiesAndSubProvinces' => self::TYPE_ARRAY, + 'searchSpecMapCenterLongitude' => self::TYPE_FLOAT, + 'searchSpecMapCenterLatitude' => self::TYPE_FLOAT, + 'searchSpecMapCenterZoom' => self::TYPE_INT, + 'numberOfMeetingsForAuto' => self::TYPE_INT, + 'autoGeocodingEnabled' => self::TYPE_BOOL, + 'countyAutoGeocodingEnabled' => self::TYPE_BOOL, + 'zipAutoGeocodingEnabled' => self::TYPE_BOOL, + 'defaultClosedStatus' => self::TYPE_BOOL, + 'enableLanguageSelector' => self::TYPE_BOOL, + 'includeServiceBodyEmailInSemantic' => self::TYPE_BOOL, + 'bmltTitle' => self::TYPE_STRING, + 'bmltNotice' => self::TYPE_STRING, + 'formatLangNames' => self::TYPE_ARRAY, + ]; + + private const SETTING_DEFAULTS = [ + 'googleApiKey' => '', + 'changeDepthForMeetings' => 0, + 'defaultSortKey' => null, + 'language' => 'en', + 'defaultDurationTime' => '01:00', + 'regionBias' => 'us', + 'distanceUnits' => 'mi', + 'meetingStatesAndProvinces' => [], + 'meetingCountiesAndSubProvinces' => [], + 'searchSpecMapCenterLongitude' => -118.563659, + 'searchSpecMapCenterLatitude' => 34.235918, + 'searchSpecMapCenterZoom' => 6, + 'numberOfMeetingsForAuto' => 10, + 'autoGeocodingEnabled' => true, + 'countyAutoGeocodingEnabled' => false, + 'zipAutoGeocodingEnabled' => false, + 'defaultClosedStatus' => true, + 'enableLanguageSelector' => false, + 'includeServiceBodyEmailInSemantic' => false, + 'bmltTitle' => 'BMLT Administration', + 'bmltNotice' => '', + 'formatLangNames' => [], + ]; + + public function up() + { + $config = $this->getConfig(); + $settingNames = array_keys(self::SETTING_TYPES); + foreach ($settingNames as $name) { + $type = self::SETTING_TYPES[$name]; + $value = $config[$name]; + if (!is_null($value)) { + $value = $this->cast($value, $type); + $value = json_encode($value); + } + DB::table('settings')->insert(['name' => $name, 'type' => $type, 'value' => $value]); + } + } + + private function cast($value, string $type): mixed + { + switch ($type) { + case self::TYPE_ARRAY: + if (is_array($value)) { + return $value; + } + if (is_string($value)) { + return $value === '' ? [] : array_map('trim', explode(',', $value)); + } + return []; + + case self::TYPE_BOOL: + return (bool)$value; + + case self::TYPE_INT: + return (int)$value; + + case self::TYPE_FLOAT: + return (float)$value; + + case self::TYPE_STRING: + default: + return (string)$value; + } + } + + private function getConfig(): array + { + // Declare all possible global variables so they're accessible + global $gkey, $gKey, $change_depth_for_meetings, $default_sort_key, $comdef_global_language; + global $default_duration_time, $region_bias, $comdef_distance_units; + global $meeting_states_and_provinces, $meeting_counties_and_sub_provinces; + global $search_spec_map_center, $number_of_meetings_for_auto; + global $auto_geocoding_enabled, $county_auto_geocoding_enabled, $zip_auto_geocoding_enabled; + global $g_defaultClosedStatus, $g_enable_language_selector; + global $g_include_service_body_email_in_semantic, $bmlt_title, $bmlt_notice, $format_lang_names; + + // If not in testing and file exists, load it + $legacyConfigFile = base_path() . '/../auto-config.inc.php'; + if (env('APP_ENV') !== 'testing' && file_exists($legacyConfigFile)) { + defined('BMLT_EXEC') or define('BMLT_EXEC', 1); + require($legacyConfigFile); + } + + return [ + 'googleApiKey' => $gkey ?? $gKey ?? self::SETTING_DEFAULTS['googleApiKey'], + 'changeDepthForMeetings' => $change_depth_for_meetings ?? self::SETTING_DEFAULTS['changeDepthForMeetings'], + 'defaultSortKey' => $default_sort_key ?? self::SETTING_DEFAULTS['defaultSortKey'], + 'language' => $comdef_global_language ?? self::SETTING_DEFAULTS['language'], + 'defaultDurationTime' => $default_duration_time ?? self::SETTING_DEFAULTS['defaultDurationTime'], + 'regionBias' => $region_bias ?? self::SETTING_DEFAULTS['regionBias'], + 'distanceUnits' => $comdef_distance_units ?? self::SETTING_DEFAULTS['distanceUnits'], + 'meetingStatesAndProvinces' => $meeting_states_and_provinces ?? self::SETTING_DEFAULTS['meetingStatesAndProvinces'], + 'meetingCountiesAndSubProvinces' => $meeting_counties_and_sub_provinces ?? self::SETTING_DEFAULTS['meetingCountiesAndSubProvinces'], + 'searchSpecMapCenterLongitude' => (isset($search_spec_map_center) ? ($search_spec_map_center['longitude'] ?? null) : null) ?? self::SETTING_DEFAULTS['searchSpecMapCenterLongitude'], + 'searchSpecMapCenterLatitude' => (isset($search_spec_map_center) ? ($search_spec_map_center['latitude'] ?? null) : null) ?? self::SETTING_DEFAULTS['searchSpecMapCenterLatitude'], + 'searchSpecMapCenterZoom' => (isset($search_spec_map_center) ? ($search_spec_map_center['zoom'] ?? null) : null) ?? self::SETTING_DEFAULTS['searchSpecMapCenterZoom'], + 'numberOfMeetingsForAuto' => $number_of_meetings_for_auto ?? self::SETTING_DEFAULTS['numberOfMeetingsForAuto'], + 'autoGeocodingEnabled' => $auto_geocoding_enabled ?? self::SETTING_DEFAULTS['autoGeocodingEnabled'], + 'countyAutoGeocodingEnabled' => $county_auto_geocoding_enabled ?? self::SETTING_DEFAULTS['countyAutoGeocodingEnabled'], + 'zipAutoGeocodingEnabled' => $zip_auto_geocoding_enabled ?? self::SETTING_DEFAULTS['zipAutoGeocodingEnabled'], + 'defaultClosedStatus' => $g_defaultClosedStatus ?? self::SETTING_DEFAULTS['defaultClosedStatus'], + 'enableLanguageSelector' => $g_enable_language_selector ?? self::SETTING_DEFAULTS['enableLanguageSelector'], + 'includeServiceBodyEmailInSemantic' => $g_include_service_body_email_in_semantic ?? self::SETTING_DEFAULTS['includeServiceBodyEmailInSemantic'], + 'bmltTitle' => $bmlt_title ?? self::SETTING_DEFAULTS['bmltTitle'], + 'bmltNotice' => $bmlt_notice ?? self::SETTING_DEFAULTS['bmltNotice'], + 'formatLangNames' => $format_lang_names ?? self::SETTING_DEFAULTS['formatLangNames'], + ]; + } + + public function down() + { + DB::table('settings')->truncate(); + } +}; diff --git a/src/database/migrations/2025_12_12_201931_fix_formats.php b/src/database/migrations/2025_12_12_201931_fix_formats.php new file mode 100644 index 000000000..d8d4c9da1 --- /dev/null +++ b/src/database/migrations/2025_12_12_201931_fix_formats.php @@ -0,0 +1,98 @@ +where('lang_enum', 'it') + ->where('key_string', 'AR') + ->doesntExist(); + if ($available) { + DB::table('comdef_formats') + ->where('lang_enum', 'it') + ->where('key_string', 'M') + ->where('name_string', 'Meditazione') + ->where('description_string', 'In questa riunione sono poste restrizioni alle modalità di partecipazione.') + ->update(['key_string' => 'AR', 'name_string' => 'Accesso ristretto']); + } + + // update the key and name for Children Welcome format in Portuguese + $available = DB::table('comdef_formats') + ->where('lang_enum', 'pt') + ->where('key_string', 'CBM') + ->doesntExist(); + if ($available) { + DB::table('comdef_formats') + ->where('lang_enum', 'pt') + ->where('key_string', 'PC') + ->where('name_string', 'Permitido Crianças') + ->where('description_string', 'Crianças são bem-vindas a essa reunião.') + ->update(['key_string' => 'CBM', 'name_string' => 'Crianças são bem-vindas']); + } + + // update the key for Candlelight format in Portuguese + $available = DB::table('comdef_formats') + ->where('lang_enum', 'pt') + ->where('key_string', 'LV') + ->doesntExist(); + if ($available) { + DB::table('comdef_formats') + ->where('lang_enum', 'pt') + ->where('key_string', 'VL') + ->where('name_string', 'Luz de velas') + ->where('description_string', 'Esta reunião acontece à luz de velas.') + ->update(['key_string' => 'LV']); + } + + // delete the duplicate ENG format for Swedish + $formats = DB::table('comdef_formats') + ->where('lang_enum', 'sv') + ->where('key_string', 'ENG') + ->where('name_string', 'Engelska') + ->where('description_string', 'Engelsktalande möte'); + $n = $formats->count(); + if ($n == 2) { + $dupId = $formats->max('id'); + DB::table('comdef_formats') + ->where('id', $dupId) + ->delete(); + } + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + // + } +}; diff --git a/src/database/migrations/2025_12_27_112435_update_danish_language_code.php b/src/database/migrations/2025_12_27_112435_update_danish_language_code.php new file mode 100644 index 000000000..bb011393e --- /dev/null +++ b/src/database/migrations/2025_12_27_112435_update_danish_language_code.php @@ -0,0 +1,67 @@ +where('lang_enum', 'dk') + ->update(['lang_enum' => 'da']); + + DB::table('comdef_service_bodies') + ->where('lang_enum', 'dk') + ->update(['lang_enum' => 'da']); + + DB::table('comdef_users') + ->where('lang_enum', 'dk') + ->update(['lang_enum' => 'da']); + + DB::table('comdef_meetings_data') + ->where('lang_enum', 'dk') + ->update(['lang_enum' => 'da']); + + DB::table('comdef_meetings_longdata') + ->where('lang_enum', 'dk') + ->update(['lang_enum' => 'da']); + + DB::table('comdef_meetings_main') + ->where('lang_enum', 'dk') + ->update(['lang_enum' => 'da']); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + DB::table('comdef_formats') + ->where('lang_enum', 'da') + ->update(['lang_enum' => 'dk']); + + DB::table('comdef_service_bodies') + ->where('lang_enum', 'da') + ->update(['lang_enum' => 'dk']); + + DB::table('comdef_users') + ->where('lang_enum', 'da') + ->update(['lang_enum' => 'dk']); + + DB::table('comdef_meetings_data') + ->where('lang_enum', 'da') + ->update(['lang_enum' => 'dk']); + + DB::table('comdef_meetings_longdata') + ->where('lang_enum', 'da') + ->update(['lang_enum' => 'dk']); + + DB::table('comdef_meetings_main') + ->where('lang_enum', 'da') + ->update(['lang_enum' => 'dk']); + } +}; diff --git a/src/database/migrations/2025_12_31_233709_clean_orphaned_format_ids.php b/src/database/migrations/2025_12_31_233709_clean_orphaned_format_ids.php new file mode 100644 index 000000000..66e18c0fa --- /dev/null +++ b/src/database/migrations/2025_12_31_233709_clean_orphaned_format_ids.php @@ -0,0 +1,75 @@ +pluck('id') + ->map(fn($id) => (string)$id) + ->flip(); + + $minId = DB::table('comdef_meetings_main')->min('id_bigint'); + $maxId = DB::table('comdef_meetings_main')->max('id_bigint'); + + if (is_null($minId) || is_null($maxId)) { + return; + } + + $chunkSize = 500; + $startId = $minId; + + while ($startId <= $maxId) { + $endId = min($startId + $chunkSize, $maxId); + + $meetings = DB::table('comdef_meetings_main') + ->whereBetween('id_bigint', [$startId, $endId]) + ->whereNotNull('formats') + ->whereNot('formats', '') + ->select('id_bigint', 'formats') + ->get(); + + foreach ($meetings as $meeting) { + $formatIds = collect(explode(',', $meeting->formats)) + ->map(fn($id) => trim($id)) + ->filter(fn($id) => $id !== ''); + + $validIds = $formatIds->filter(fn($id) => $validFormatIds->has($id)); + $cleanedFormats = $validIds->implode(','); + + if ($cleanedFormats !== $meeting->formats) { + DB::table('comdef_meetings_main') + ->where('id_bigint', $meeting->id_bigint) + ->update(['formats' => $cleanedFormats]); + } + } + + $startId = $endId + 1; + } + } + + /** + * Reverse the migrations. + * + * Note: This migration cannot be reliably reversed because we don't know + * which format IDs were removed. The down() method is intentionally left empty. + */ + public function down(): void + { + // Cannot reverse this migration - we don't know which format IDs were orphaned + } +}; diff --git a/src/database/migrations/2026_01_04_123352_set_langenum_to_app_locale.php b/src/database/migrations/2026_01_04_123352_set_langenum_to_app_locale.php new file mode 100644 index 000000000..73b96d336 --- /dev/null +++ b/src/database/migrations/2026_01_04_123352_set_langenum_to_app_locale.php @@ -0,0 +1,26 @@ +update(['lang_enum' => config('app.locale')]); + Schema::table('comdef_users', function ($table) { + $table->string('target_language', 10)->nullable(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + } +}; diff --git a/src/index.php b/src/index.php index e5d477e7b..bcdb1cad9 100644 --- a/src/index.php +++ b/src/index.php @@ -16,7 +16,7 @@ | */ -if (file_exists($maintenance = __DIR__.'/storage/framework/maintenance.php')) { +if (file_exists($maintenance = __DIR__ . '/storage/framework/maintenance.php')) { require $maintenance; } diff --git a/src/lang/dk/change_detail.php b/src/lang/da/change_detail.php similarity index 100% rename from src/lang/dk/change_detail.php rename to src/lang/da/change_detail.php diff --git a/src/lang/dk/change_type.php b/src/lang/da/change_type.php similarity index 100% rename from src/lang/dk/change_type.php rename to src/lang/da/change_type.php diff --git a/src/lang/da/language_name.php b/src/lang/da/language_name.php new file mode 100644 index 000000000..120546be5 --- /dev/null +++ b/src/lang/da/language_name.php @@ -0,0 +1,5 @@ + 'Dansk', +]; diff --git a/src/lang/dk/main_prompts.php b/src/lang/da/main_prompts.php similarity index 100% rename from src/lang/dk/main_prompts.php rename to src/lang/da/main_prompts.php diff --git a/src/lang/dk/weekdays.php b/src/lang/da/weekdays.php similarity index 100% rename from src/lang/dk/weekdays.php rename to src/lang/da/weekdays.php diff --git a/src/lang/de/language_name.php b/src/lang/de/language_name.php new file mode 100644 index 000000000..1c523bc09 --- /dev/null +++ b/src/lang/de/language_name.php @@ -0,0 +1,5 @@ + 'Deutsch', +]; diff --git a/src/lang/en/language_name.php b/src/lang/en/language_name.php new file mode 100644 index 000000000..41a720cbb --- /dev/null +++ b/src/lang/en/language_name.php @@ -0,0 +1,5 @@ + 'English', +]; diff --git a/src/lang/es/language_name.php b/src/lang/es/language_name.php new file mode 100644 index 000000000..4357b18be --- /dev/null +++ b/src/lang/es/language_name.php @@ -0,0 +1,5 @@ + 'Español', +]; diff --git a/src/lang/fa/language_name.php b/src/lang/fa/language_name.php new file mode 100644 index 000000000..f4c72a29a --- /dev/null +++ b/src/lang/fa/language_name.php @@ -0,0 +1,5 @@ + 'فارسی', +]; diff --git a/src/lang/fr/language_name.php b/src/lang/fr/language_name.php new file mode 100644 index 000000000..2e9f0e208 --- /dev/null +++ b/src/lang/fr/language_name.php @@ -0,0 +1,5 @@ + 'Français', +]; diff --git a/src/lang/it/language_name.php b/src/lang/it/language_name.php new file mode 100644 index 000000000..1c2f6d7df --- /dev/null +++ b/src/lang/it/language_name.php @@ -0,0 +1,5 @@ + 'Italiano', +]; diff --git a/src/lang/pl/language_name.php b/src/lang/pl/language_name.php new file mode 100644 index 000000000..2875e4de7 --- /dev/null +++ b/src/lang/pl/language_name.php @@ -0,0 +1,5 @@ + 'Polski', +]; diff --git a/src/lang/pt/language_name.php b/src/lang/pt/language_name.php new file mode 100644 index 000000000..5c943b21c --- /dev/null +++ b/src/lang/pt/language_name.php @@ -0,0 +1,5 @@ + 'Português', +]; diff --git a/src/lang/ru/language_name.php b/src/lang/ru/language_name.php new file mode 100644 index 000000000..5368e24cf --- /dev/null +++ b/src/lang/ru/language_name.php @@ -0,0 +1,5 @@ + 'Русский', +]; diff --git a/src/lang/sv/language_name.php b/src/lang/sv/language_name.php new file mode 100644 index 000000000..6ab0d8e16 --- /dev/null +++ b/src/lang/sv/language_name.php @@ -0,0 +1,5 @@ + 'Svenska', +]; diff --git a/src/legacy/client_interface/contact.php b/src/legacy/client_interface/contact.php deleted file mode 100644 index c3a3cf151..000000000 --- a/src/legacy/client_interface/contact.php +++ /dev/null @@ -1,435 +0,0 @@ - The ID of the meeting being referenced. - service_body_id= The ID of the Service body associated with the meeting. - from_address= A validly-formatted email address to be used as the "FROM:" line. - message= The message text. - - All of these must be supplied, and the Service body ID needs to jive with the one associated with the meeting ID. - That's not something that spammers will be easily able to determine; especially when you consider how worthless the recipient will be to them. - - The contacts are tiered in this manner: - - If a contact is provided for the meeting itself (email_contact field, or contact_email_1), then that contact is used. - - If there are multiple contacts using the default contact structure (contact_email_1, contact_email_2), then we will send to both of them. - - If no individual contacts are provided for a meeting, then we will use the email contact for the Service body for that meeting. - - If no Service body contact is provided, then the email will be sent to the Server Administrator. - - If no email contacts are provided anywhere, the email will not be sent. - - A simple integer response is returned. 1, if the email was successfully sent, 0 if email contacts are disallowed, -1, if no email contacts are available for this meeting, -2, if the from email address is invalid, -3 if the email was flagged as spam, and -4 if there was some error encountered while sending. - - If the meeting ID is 0 (or there is no input), then the message text and from are ignored, and this is considered a test to see if email is supported. A response of 1 is yes, 0, otherwise. - - This won't work if the $g_enable_email_contact = TRUE; line is not in the auto-config.inc.php file. - - If you want to include all the Service body contacts (multiple recipients are possible), then set $include_service_body_admin_on_emails = TRUE; in the config file. - - This file is part of the Basic Meeting List Toolbox (BMLT). - - Find out more at: https://bmlt.app - - BMLT is free software: you can redistribute it and/or modify - it under the terms of the MIT License. - - BMLT is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - MIT License for more details. - - You should have received a copy of the MIT License along with this code. - If not, see . -*/ - -global $g_mail_debug; - -$g_mail_debug = false; ///< Set this to TRUE to output the email as an echo, instead of sending it. - -if (preg_match("/localhost/", $_SERVER['SERVER_NAME'])) { - $g_mail_debug = true; // We always debug for localhost testing. -} - -/***********************************************************************/ -/** \brief This analyzes an input string for obvious spam signatures. - This looks for attempts to insert headers into the From: line. - - \returns a Boolean. TRUE if the message appears to be spam. -*/ -function analyzeFromLine( - $inFrom ///< The message from line as a text string. -) { - $inFrom = strtolower($inFrom); - - $ret = !((false == strpos($inFrom, "\r")) && (false == strpos($inFrom, "\n")) && (false == strpos($inFrom, ";")) && (false == strpos($inFrom, "to:")) && (false == strpos($inFrom, "cc:")) && (false == strpos($inFrom, "bc:"))); - - return $ret; -} - -/***********************************************************************/ -/** \brief This analyzes an input string for obvious spam signatures (mostly checking for URLs). - This is VERY basic, but it will catch 99% of the usual spam types. - Cribbed from here: http://wcetdesigns.com/tutorials/2011/11/30/detect-url-in-string.html - - \returns a Boolean. TRUE if the message appears to be spam. -*/ -function analyzeMessageContent( - $inMessage ///< The message as a text string. -) { - $ret = false; - $count = 0; - - $p = '#^(http(s)?|ftp)://([a-z0-9_-]+.)+([a-z]{2,}){1}((:|/)(.*))?$#'; - - $w = preg_split("/\s+/", $inMessage, -1, PREG_SPLIT_NO_EMPTY); - - foreach ($w as $s) { - if (preg_match($p, $s)) { - if (1 < $count++) { // More than 2 is spam. - $ret = true; - break; - } - } - } - - return $ret; -} - -/***********************************************************************/ -/** \brief This analyzes email address (or a list of them), and returns TRUE if they are OK (as formatted). - \returns a Boolean. TRUE if the emails are OK. -*/ -function isValidEmailAddress( - $in_test_address ///< The email address (or a list or array) to be checked. -) { - $valid = false; - if (isset($in_test_address)) { - if (!is_array($in_test_address)) { - $in_test_address = explode(",", $in_test_address); // See if we have a list. - } - - // Start off optimistic. - $valid = true; - - // If we have more than one address, we iterate through each one. - foreach ($in_test_address as $addr_elem) { - // This splits any name/address pair (ex: "Jack Schidt" ) - $addr_temp = preg_split("/ 1) { // We also want to trim off address brackets. - $addr_elem = trim($addr_temp[1], "<>"); - } else { - $addr_elem = trim($addr_temp[0], "<>"); - } - - // Test for valid email address. - $regexp = "/^([a-z0-9\_\.\-]+?)@([a-z0-9\-]+)(\.[a-z0-9\-]+)*(\.[a-z]{2,6})$/"; - - if (!preg_match($regexp, strtolower($addr_elem))) { - $valid = false; - break; - } - } - } - - return $valid; -} - -/***********************************************************************/ -/** \brief This simplifies one single email address, by stripping away cruft. - - \returns a "cleaned" email address. -*/ -function simplifyEmailAddress($in_orig_address) -{ - $addr_temp = preg_split("/ 1) { // We also want to trim off address brackets. - $addr_elem = trim($addr_temp[1], " <>"); - } else { - $addr_elem = trim($addr_temp[0], " <>"); - } - - if (isValidEmailAddress($addr_elem)) { - return $addr_elem; - } - - return ""; -} - -/***********************************************************************/ -/** \brief This actually sends the email. - - \returns a Boolean. TRUE if successful. -*/ -function sendEMail( - $in_to_address, - $in_from_address, - $in_subject = "", - $in_body = "" -) { - $success = false; - - $addlParam = $in_from_address; - - if ($addlParam) { - $addlParam = "-f $addlParam"; - } - - // The body is not sent in the plain text portion of the - // mail() function. Instead, it is put in the headers. - - $headers = ""; - $headers .= "From: $in_from_address\n"; - // Make sure our endlines are correct, and unescape any escaped quotes. - $in_body = preg_replace("/\r\n/", "\n", $in_body); - $in_body = stripslashes(preg_replace("/\r/", "\n", $in_body)); - $in_body = stripslashes(preg_replace("/\n+/", "\n", $in_body)); - $subject = stripslashes($in_subject); - - // Headers precede the body. - $headers .= $in_body; - - global $g_mail_debug; - - if ($g_mail_debug) { - $disp = "To: ".htmlspecialchars($in_to_address)."\n"; - $disp .= "Subject: ".htmlspecialchars($subject)."\n"; - $disp .= htmlspecialchars($headers); - echo "
$disp
"; - $success = true; - } else { - // The "Message" parameter is blank, because we are using - // the headers to send the body. Bit more technical, but - // more effective. - $success = mail($in_to_address, $subject, "", $headers, $addlParam); - } - - return $success; -} - -/***********************************************************************/ -/* MAIN CONTEXT */ -/***********************************************************************/ - -$ret = 0; // We start off assuming that email contact is disabled. -$meeting_id = 0; - -if (isset($_GET['meeting_id'])) { - $meeting_id = intval($_GET['meeting_id']); -} - -// If this is just a test, we respond with the capability. -if (0 == $meeting_id) { - if (file_exists(dirname(dirname(dirname(__FILE__))).'/../auto-config.inc.php')) { - defined('BMLT_EXEC') or define('BMLT_EXEC', 1); - // We check to make sure that we are supporting the capability. - require_once(dirname(dirname(dirname(__FILE__))).'/../auto-config.inc.php'); - $ret = $g_enable_email_contact ? 1 : 0; - } -} else { - if (isset($_GET['service_body_id'])) { - $service_body_id = intval($_GET['service_body_id']); - if (!$service_body_id) { - $service_body_id = intval($_GET['service_body_bigint']); - } - } - - if (isset($_GET['message'])) { - $message_text = $_GET['message']; - } - - if (isset($_GET['from_address'])) { - $from_address = $_GET['from_address']; - } - - $isspam = false; - - foreach ($_GET as $key => $value) { - $key = strtolower(strval($key)); - - // Any attempt to sneak in extra fields automatically marks this as spam. - if (($key != 'meeting_id') && ($key != 'service_body_id') && ($key != 'service_body_bigint') && ($key != 'from_address') && ($key != 'message')) { - if ($g_mail_debug) { - echo ( "$key is invalid
" ); - } - - $isspam = true; - break; - } - } - - if (!$isspam) { - $isspam = isset($from_address) ? analyzeFromLine($from_address) : false; - - if (!$isspam) { - if (isset($from_address) ? isValidEmailAddress($from_address) : true) { - $isspam = isset($message_text) ? analyzeMessageContent($message_text) : false; - - if (!$isspam) { - if (file_exists(dirname(dirname(dirname(__FILE__))).'/../auto-config.inc.php')) { - defined('BMLT_EXEC') or define('BMLT_EXEC', 1); - - // We check to make sure that we are supporting the capability. - require_once(dirname(dirname(dirname(__FILE__))).'/../auto-config.inc.php'); - - if ($g_enable_email_contact && $meeting_id) { - require_once(dirname(dirname(__FILE__)).'/server/c_comdef_server.class.php'); - $server = c_comdef_server::MakeServer(); - - if ($server instanceof c_comdef_server) { - $email_contacts = array(); // This will contain our meeting email contact list. - - $meeting_object = c_comdef_server::GetOneMeeting($meeting_id); - - if ($meeting_object instanceof c_comdef_meeting) { // We must have a valid meeting. - // This is a pretty good spamtrap. The submission must have both the meeting ID and the valid Service body ID. - if (isset($service_body_id) && $service_body_id && ($service_body_id == $meeting_object->GetServiceBodyID())) { - if ($meeting_object->GetEmailContact()) { // The direct contact is placed first in the queue. - $email = simplifyEmailAddress($meeting_object->GetEmailContact()); - - if ($email) { - $email_contacts[] = $email; - } - } - - // We now walk up the hierarchy, and add contacts as we find them. We use the emails set in the Service body admin, not individual accounts. - - $service_body = $meeting_object->GetServiceBodyObj(); - - do { - if ($service_body && $service_body->GetContactEmail()) { - $email = simplifyEmailAddress($service_body->GetContactEmail()); - - if ($email && !in_array($email, $email_contacts)) { // Make sure we don't already have it. - $email_contacts[] = $email; - } - } - - // We don't recurse if we aren't supposed to - $service_body = isset($include_every_admin_on_emails) && $include_every_admin_on_emails ? $service_body->GetOwnerIDObject() : null; - } while ($service_body); - - // The one exception is the Server Administrator, and we get that email from the individual account. - - if (isset($include_every_admin_on_emails) && $include_every_admin_on_emails) { // The Server admin is not involved unless we are cascading. - $server_admin_user = c_comdef_server::GetUserByIDObj(1); - - if ($server_admin_user && $server_admin_user->GetEmailAddress()) { - $email = simplifyEmailAddress($server_admin_user->GetEmailAddress()); - - if ($email) { - $email_contacts[] = $email; - } - } - } - - // At this point, we have one or more email addresses in our $email_contacts array. It's possible that the Server Admin may be the only contact. - - if (count($email_contacts)) { // Make sure that we have something. - $to_line = null; - - if ((1 < count($email_contacts)) && $include_service_body_admin_on_emails) { // See if we are including anyone else. - $to_line = implode(",", $email_contacts); - } else { - $to_line = $email_contacts[0]; // Otherwise, just the primary contact. - } - - if ($to_line) { // Assuming all went well, we have a nice to line, here. - if (isValidEmailAddress($to_line)) { // Make sure our email addresses are valid. - $local_strings = c_comdef_server::GetLocalStrings(); - - $subject = sprintf($local_strings['email_contact_strings']['meeting_contact_form_subject_format'], $meeting_object->GetLocalName()); - $dirn = dirname(( dirname($_SERVER['PHP_SELF']))); - if ('/' == $dirn) { - $dirn = ''; - } - $start_time = explode(':', $meeting_object->GetMeetingDataValue('start_time')); - unset($start_time[2]); - $start_time = implode(':', $start_time); - $root_dirname = 'http://'.$_SERVER['SERVER_NAME'].(($_SERVER['SERVER_PORT'] != 80) ? ':'.$_SERVER['SERVER_PORT'] : '').$dirn; - $url1 = $root_dirname.'/?single_meeting_id='.$meeting_id; - $url2 = $root_dirname.'/?edit_meeting='.$meeting_id; - $body = sprintf( - $local_strings['email_contact_strings']['meeting_contact_message_format'], - $message_text, - $meeting_object->GetLocalName(), - $start_time, - $local_strings['weekdays'][$meeting_object->GetMeetingDataValue('weekday_tinyint')], - $url1, - $url2 - ); - if (sendEMail($to_line, $from_address, $subject, $body)) { - $ret = 1; - } else { - $ret = -4; - } - } else { - $ret = -1; - } - } else { - $ret = -1; // Should never happen. - } - } else { - $ret = -1; - } - } else { - if ($g_mail_debug) { - die("Content Considered Spam (Service body check failed)"); - } - - $ret = -3; - } - } - } - } - - // If this is just a test, we respond with the capability. - if (0 == $meeting_id) { - $ret = $g_enable_email_contact ? 1 : 0; - } - } else { - die("SERVER NOT INITIALIZED"); - } - } else { - if ($g_mail_debug) { - die("Content Considered Spam"); - } - - $ret = -3; - } - } else { - if ($g_mail_debug) { - die("From Address Invalid"); - } - - $ret = -2; - } - } else { - if ($g_mail_debug) { - die("From Address Considered Spam"); - } - - $ret = -3; - } - } else { - if ($g_mail_debug) { - die("Extra parameters (considered spam)"); - } - - $ret = -3; - } -} - -echo intval($ret); diff --git a/src/legacy/client_interface/csv/c_comdef_meeting_search_manager.class.php b/src/legacy/client_interface/csv/c_comdef_meeting_search_manager.class.php deleted file mode 100755 index 5c36991fa..000000000 --- a/src/legacy/client_interface/csv/c_comdef_meeting_search_manager.class.php +++ /dev/null @@ -1,1567 +0,0 @@ -. -*/ - -defined('BMLT_EXEC') or die('Cannot Execute Directly'); // Makes sure that this file is in the correct context. - -require_once(dirname(__FILE__)."/../../server/c_comdef_server.class.php"); -require_once(dirname(__FILE__)."/../../server/shared/classes/VenueType.php"); - -/// A class to control the basic common functionality of all meeting searches. -// phpcs:disable PSR1.Classes.ClassDeclaration.MissingNamespace -// phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps -class c_comdef_meeting_search_manager -// phpcs:emable PSR1.Classes.ClassDeclaration.MissingNamespace -// phpcs:enable Squiz.Classes.ValidClassName.NotCamelCaps -{ - /// These fields are used to specify the search criteria. - protected $_formats = null; /**< An array of integers. These are formats. The filtering will be an "AND" filtering, so qualified meetings - must have all of the given formats. The key is the format's shared ID, and the value will be one of these: - - -1 NOT (exclude all meetings that contain this format from the search). - - 0 No preference (This format will not be a consideration in the search). - - 1 Return meetings that contain this format. - - Default is 0 for all. If no formats are specified (either 1 or -1), then formats will not be a consideration - in the meeting search. If any format is specified as 1, then ONLY meetings with the given format will be - considered in the search, and you must explicitly set any other formats you wish found. - */ - protected $_formats_comparison_operator = "AND"; /**< A string, controls the comparison operator used for included formats. Valid values are AND and OR. - * */ - - protected $_service_bodies = null; /**< An array of integers. The key is the ID for a Service Body, and the value is one of these: - - -1 NOT (exclude all meetings that contain this Service Body from the search). - - 0 No preference (This Service Body will not be a consideration in the search). - - 1 Return meetings that contain this Service Body. - - Default is 0 for all. If no Service Bodies are specified (either 1 or -1), then Service Bodies will not be a - consideration in the meeting search. If any Service Body is specified as 1, then ONLY meetings with the given - Service Body will be considered in the search, and you must explicitly set any other Service Bodies you wish found. - */ - protected $_languages = null; /**< An array of integers. The key is the language enum, and the value is as follows: - - -1 NOT (exclude all meetings that have this language from the search). - - 0 No preference (This language will not be a consideration in the search). - - 1 Return meetings that have this language. - - Default is 0 for all. If no languages are specified (either 1 or -1), then language will not be a - consideration in the meeting search. If any language is specified as 1, then ONLY meetings with the given - language will be considered in the search, and you must explicitly set any other language you wish found. - */ - protected $_weekdays = null; /**< An array of integers. The key is the weekday (1 = Sunday, 7 = Saturday), and the value is as follows: - - -1 NOT (exclude all meetings that occur on this weekday from the search). - - 0 No preference (This weekday will not be a consideration in the search). - - 1 Return meetings that occur on this weekday. - - Default is 0 for all. If no weekdays are specified (either 1 or -1), then the weekday will not be a - consideration in the meeting search. If any weekday is specified as 1, then ONLY meetings that occur on - the given weekday will be considered in the search, and you must explicitly set any other weekday you wish found. - */ - - protected $_venue_types = null; // An array of Venue types, positive or negative. Negative venue types are excluded. - - /// These specify the start time and duration of the meeting. The start time can be specified as a "window." - protected $_start_after = null; ///< An epoch time (seconds, as returned by time()), that denotes the earliest starting time allowed. - protected $_start_before = null; ///< An epoch time (seconds, as returned by time()), that denotes the latest starting time allowed. - protected $_end_before = null; ///< An epoch time (seconds, as returned by time()), that denotes the latest ending time allowed. - protected $_min_duration = null; ///< The number of seconds a meeting should last as a minimum. - protected $_max_duration = null; ///< The number of seconds a meeting can last, at most. - - /// These specify the search radius (We store it in kilometers). - protected $_search_radius = null; ///< If this is not null, it needs to be a positive, floating-point number, indicating the radius, in Kilometers. - protected $_search_radius_count = null; ///< If this is not null, it needs to be a positive integer, indicating the number of meetings to find automatically. - protected $_search_center_long = null; ///< If $_search_radius is not null, this needs to be a floating-point number that indicates the longitude, in degrees, of the search center. - protected $_search_center_lat = null; ///< If $_search_radius is not null, this needs to be a floating-point number that indicates the latitude, in degrees, of the search center. - - /// We allow a broad string search that goes through all the text items. In English and Spanish, it uses metaphone, which is a "sounds like" phonetic search. - protected $_search_string = null; ///< A string to be located from within the results. This search is done after all of the previous ones. This is applied at the end. - protected $_search_string_all_words = false; ///< A Boolean. If this is true, then all of the words in a phrase must be present. - protected $_search_string_literal = false; ///< A Boolean. If this is true, then the spelling must be literal. - - /// This allows you to filter out a particular value for a key - protected $_meeting_key = null; /**< A string. This is the xact name of the key to match. - NOTE: As of Version 1.5, this can be an array of strings (it can still be a single string). The array should contain the names of string fields. - */ - protected $_meeting_key_value = null; /**< A string. The value to match. - NOTE: As of Version 1.5, this is matched with a metaphone match, as well as the RegEx match. - */ - protected $_meeting_key_match_case = false; /**< If true, the case must match. Default is false. - NOTE: As of Version 1.5, setting this to TRUE also stops the metaphone search. - */ - protected $_meeting_key_contains = false; ///< If this is false, then the string must be complete. Default is false (literal). - - /// This contains a list of IDs of individual meetings. If it is set, then all other search parameters are ignored. - protected $_meeting_id_array = null; ///< An array of positive integers. The Ids of meetings to find. If this is set, all other search criteria are ignored. - - /// This indicates whether the search should include, exclude, or focus on "published" meetings. - protected $_published_search = 0; /**< This only counts if the searcher is a logged-in admin. The value can be: - - -1 Search for ONLY unpublished meetings - - 0 Search for published and unpublished meetings. - - 1 Search for ONLY published meetings. - */ - protected $_sort_search_by_distance = false; ///< If this is true, then the search results may be sorted by distance from the geo center. - - /// This contains the search results. - protected $_search_results = null; ///< A c_comdef_meetings object. If this is null, a new search is performed. This contains the entire search results. - - private $sort_array = null; ///< This contains an array of strings that represent the sort keys. - private $sort_desc = false; ///< This is set to true if the sort is a reverse sort. - private $sort_depth = 3; ///< An integer. This is how far back a staged sort goes. Default is 3. 0 is forever. - - /// This refers to portions of a larger search (pages). - private $_results_per_page = 0; ///< The number of meetings to list per page. - private $_pageno = 0; ///< An integer. The page number represented by this object. If $_results_per_page is 0, this is ignored. - - /// If this isn't the root, then this will be a reference to the root. - private $_my_root = null; ///< A reference to an instance of c_comdef_meeting_search_manager -The root object. - - private $_my_server = null; ///< A reference to a c_comdef_server object. This is the server to be used for the search. - - /*******************************************************************/ - /** \brief Constructor. - */ - public function __construct( - $in_results_per_page = 0, ///< An integer that defines how many results per page you want to see. 0 (default) is all in one page. - c_comdef_meeting_search_manager &$in_parent = null, ///< A reference to an existing c_comdef_meeting_search_manager object. - c_comdef_meetings &$in_search_results = null, ///< A reference to some pre-parsed search results. - $in_pageno = 0 ///< An integer. The page of the main search this is from. - ) { - // If this is a page of results, we set up the object to reference the root. - if ($in_parent instanceof c_comdef_meeting_search_manager) { - $this->_my_root = $in_parent; - // These all reference the root object's values. - $this->_formats = $in_parent->_formats; - $this->_formats_comparison_operator = $in_parent->_formats_comparison_operator; - $this->_service_bodies = $in_parent->_service_bodies; - $this->_languages = $in_parent->_languages; - $this->_weekdays = $in_parent->_weekdays; - $this->_venue_types = $in_parent->_venue_types; - $this->_start_after = $in_parent->_start_after; - $this->_start_before = $in_parent->_start_before; - $this->_end_before = $in_parent->_end_before; - $this->_min_duration = $in_parent->_min_duration; - $this->_max_duration = $in_parent->_max_duration; - $this->_search_radius = $in_parent->_search_radius; - $this->_search_center_long = $in_parent->_search_center_long; - $this->_search_center_lat = $in_parent->_search_center_lat; - $this->_search_string = $in_parent->_search_string; - $this->_meeting_id_array = $in_parent->_meeting_id_array; - $this->_published_search = $in_parent->_published_search; - - $this->_my_server = $in_parent->_my_server; - - // These may get changed by this instance. - $this->sort_array = $in_parent->sort_array; - $this->sort_desc = $in_parent->sort_desc; - - // These are passed in and set at construction - $this->_pageno = $in_pageno; - $this->_search_results = $in_search_results; - } else // If we are the root object, we start clean. - { - // See if the caller has requested a number of results per page. - if ($in_results_per_page) { - $this->_results_per_page = $in_results_per_page; - } - - $this->_my_server = c_comdef_server::MakeServer(); // We initialize the server. - - $this->SetUpFormats(); // We set the formats array. - $this->SetUpServiceBodies(); // We set the Service Bodies array. - $this->SetUpLanguages(); // We set the Languages array. - - // Set up the weekday array (1 = Sunday, 7 = Saturday ). - $this->_weekdays = null; - for ($wd = 1; $wd < 8; $wd++) { - $this->_weekdays[$wd] = 0; - } - - $this->_venue_types = null; - $this->_venue_types[VenueType::IN_PERSON] = 0; - $this->_venue_types[VenueType::VIRTUAL] = 0; - $this->_venue_types[VenueType::HYBRID] = 0; - - // This is the default sort. - $this->sort_array = array ( "lang_enum", "weekday_tinyint", "start_time", "id_bigint" ); - - // We have no search parameters or results at this point. - } - } - - /*******************************************************************/ - /** \brief Sets an internal array of integers, containing the Shared IDs for - all available formats on the server. They are initialized to 0 (neutral). - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function SetUpFormats() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $this->_formats = null; - - $formats = $this->GetAvailableFormats(); - - // Basic error checking. - if (is_array($formats) && count($formats)) { - // We look in the server's local language (in case there are no other translations). - $my_lang = $this->_my_server->GetLocalLang(); - - $er = $formats[$my_lang]; - - if (is_array($er) && count($er)) { - foreach ($er as $key => $value) { // We ignore the value. - $this->_formats[$key] = 0; - } - } - } - } - - /*******************************************************************/ - /** \brief Accessor -Get a reference to the $_formats field. - - \returns a reference to the $_formats field, which is an array of integers. - The key is the format's shared ID, and the value will be one of these: - - -1 NOT (exclude all meetings that contain this format from the search). - - 0 No preference (This format will not be a consideration in the search). - - 1 Return meetings that contain this format. - - Default is 0 for all. If no formats are specified (either 1 or -1), then formats will not be a consideration - in the meeting search. If any format is specified as 1, then ONLY meetings with the given format will be - considered in the search, and you must explicitly set any other formats you wish found. - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function &GetFormats() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - return $this->_formats; - } - - /*******************************************************************/ - /** \brief Sets a key/value search. - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function SetKeyValueSearch( - $in_meeting_key, ///< A string. This is the exact name of the key to match. - $in_meeting_key_value, ///< A string. The value to match. - $in_meeting_key_match_case = false, ///< If true, the case must match. Default is false. - $in_meeting_key_contains = true ///< If this is false, then the string must be complete. Default is true (contains). - ) { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $this->_meeting_key = $in_meeting_key; - $this->_meeting_key_value = $in_meeting_key_value; - $this->_meeting_key_match_case = $in_meeting_key_match_case; - $this->_meeting_key_contains = $in_meeting_key_contains; - } - - /*******************************************************************/ - /** \brief Sets the sort by distance flag. - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function SetSortByDistance( - $in_sort_search_by_distance = false ///< A Boolean. False is default. - ) { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $this->_sort_search_by_distance = ($in_sort_search_by_distance != false); - } - - /*******************************************************************/ - /** \brief Sets an internal array of integers, containing the IDs for - all available service bodies on the server. They are initialized - to 0 (neutral). - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function SetUpServiceBodies() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $this->_service_bodies = array(); - - // Basic error checking. - if ($this->_my_server instanceof c_comdef_server) { - // Start by getting the service bodies aggregator object. - $bodies = $this->_my_server->GetServiceBodyArray(); - if (is_array($bodies) && count($bodies)) { - foreach ($bodies as $body) { - $key = $body->GetID(); - $this->_service_bodies[$key] = 0; - } - } - } - } - - /*******************************************************************/ - /** \brief Accessor -Get the number of results per page. - - \returns an integer. - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function GetResultsPerPage() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $ret = 0; - - // This is kept in the root object. - if (!$this->_my_root) { - $ret = $this->_results_per_page; - } elseif ($this->GetRootObject() instanceof c_comdef_meeting_search_manager) { - $ret = $this->GetRootObject()->GetResultsPerPage(); - } - - return $ret; - } - - /*******************************************************************/ - /** \brief Accessor -Set the number of results per page. - This will only work on the root object. - - \returns a boolean. If the operation was successful, it is true. False otherwise. - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function SetResultsPerPage( - $in_results_per_page ///< A positive integer. If it is 0, then all results will be returned in one page. - ) { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $ret = false; - - if (!$this->_my_root) { - $this->_results_per_page = $in_results_per_page; - $ret = true; - } - - return $ret; - } - - /*******************************************************************/ - /** \brief Accessor -Get the page number of this set. - - \returns an integer. - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function GetPageNo() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - return $this->_pageno; - } - - /*******************************************************************/ - /** \brief Accessor -Get the index (1 - based) of the first meeting in this page. - - \returns an integer. - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function GetFirstIndexInPage() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - return ($this->GetResultsPerPage() * ($this->GetPageNo() - 1)) + 1; - } - - /*******************************************************************/ - /** \brief Accessor -Get the index (1 - based) of the last meeting in this page. - - \returns an integer. - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function GetLastIndexInPage() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - return ($this->GetFirstIndexInPage() + $this->GetNumberOfResultsInThisPage()) - 1; - } - - /*******************************************************************/ - /** \brief Accessor -Get the page number of this set. - - \returns an integer. - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function GetNumberOfPages() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $ret = 0; - - $respp = $this->GetResultsPerPage(); - $resnum = $this->GetNumberOfResults(); - - if ($respp > 0) { - $ret = intval(($resnum + ($respp - 1)) / $respp); - } elseif ($resnum > 0) { - $ret = 1; - } - - return $ret; - } - - /*******************************************************************/ - /** \brief Accessor -Get the total number of meetings found. - This gives the TOTAL number found, not just the subset in this page. - - \returns an integer. - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function GetNumberOfResults() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $ret = 0; - - if (!$this->_my_root && $this->_search_results instanceof c_comdef_meetings) { - $ret = $this->_search_results->GetNumMeetings(); - } elseif ($this->_my_root instanceof c_comdef_meeting_search_manager) { - $ret = $this->_my_root->GetNumberOfResults(); - } - - return $ret; - } - - /*******************************************************************/ - /** \brief Accessor -Get the number of meetings in this page. - - \returns an integer. - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function GetNumberOfResultsInThisPage() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $ret = 0; - - if ($this->_search_results instanceof c_comdef_meetings) { - $ret = $this->_search_results->GetNumMeetings(); - } - - return $ret; - } - - /*******************************************************************/ - /** \brief Accessor -Get the number of meetings in this page. - - This system allows each page to be treated independently, like allowing - different sorts without re-sorting the entire search. - - This object needs to be the "root" object to return a page. - - \returns a new instance (not a reference) to a c_comdef_meeting_search_manager - object, containing a subset of the meetings to fill this one page. - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function GetPageOfResults( - $in_page_no = 1 ///< A positive integer. This should be 1 to $this->GetNumberOfPages() (1-based) - ) { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - if ($in_page_no < 1) { // Can't be less than 1. - $in_page_no = 1; - } - - if ($in_page_no > $this->GetNumberOfPages()) { // Can't be greater than the last page. - $in_page_no = $this->GetNumberOfPages(); - } - - $ret = null; - - // We get pages from the root at all times. - if (!$this->_my_root && $this->_search_results instanceof c_comdef_meetings) { - // This is the starting index for our page of results. - $main_array_1 = $this->_search_results->GetMeetingObjects(); - $main_array = array(); - foreach ($main_array_1 as $meeting) { - array_push($main_array, $meeting); - } - - $ret_array = array(); - $min = $this->GetResultsPerPage() * ($in_page_no - 1); - $actual = intval($this->GetResultsPerPage()); - if ($actual > 0) { - $max = min(count($main_array), $min + $this->GetResultsPerPage()); - } else { - $max = $this->GetNumberOfResults(); - } - - for ($index = intval($min); $index < intval($max); $index++) { - if ($main_array[$index] instanceof c_comdef_meeting) { - $data = $main_array[$index]->GetMeetingData(); - if (is_array($data) && count($data)) { - $ret_array[$data['id_bigint']] = $main_array[$index]; - } - } - } - - if (count($ret_array)) { - $resultsObj = new c_comdef_meetings($this->_search_results->GetParentObj(), $ret_array); - - if ($resultsObj instanceof c_comdef_meetings) { - $ret = new c_comdef_meeting_search_manager(0, $this, $resultsObj, $in_page_no); - } - } - } elseif ($this->_my_root instanceof c_comdef_meeting_search_manager) { - $ret = $this->_my_root->GetPageOfResults($in_page_no); - } - - return $ret; - } - - /*******************************************************************/ - /** \brief Accessor -Get a reference to the $_service_bodies field. - - \returns a reference to the $_service_bodies field. - The key is the Service Body ID. The value is as follows: - - -1 NOT (exclude all meetings that contain this Service Body from the search). - - 0 No preference (This Service Body will not be a consideration in the search). - - 1 Return meetings that contain this Service Body. - - Default is 0 for all. If no Service Bodies are specified (either 1 or -1), then Service Bodies will not be a - consideration in the meeting search. If any Service Body is specified as 1, then ONLY meetings with the given - Service Body will be considered in the search, and you must explicitly set any other Service Bodies you wish found. - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function &GetServiceBodies() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - return $this->_service_bodies; - } - - /*******************************************************************/ - /** \brief Sets up an internal array of languages. - The array uses the language enum as the key, and the -1->0->1 - form as the selector. - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function SetUpLanguages() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $this->_languages = null; - - // Basic error checking. - if ($this->_my_server instanceof c_comdef_server) { - $langs = $this->_my_server->GetServerLangs(); - - if (is_array($langs) && count($langs)) { - foreach ($langs as $key => $value) { - $this->_languages[$key] = 0; - } - } - } - } - - /*******************************************************************/ - /** \brief Accessor -Get a reference to the $_languages field. - - \returns a reference to the $_languages field. - The key is the language enum, and the value is as follows: - - -1 NOT (exclude all meetings that have this language from the search). - - 0 No preference (This language will not be a consideration in the search). - - 1 Return meetings that have this language. - - Default is 0 for all. If no languages are specified (either 1 or -1), then language will not be a - consideration in the meeting search. If any language is specified as 1, then ONLY meetings with the given - language will be considered in the search, and you must explicitly set any other language you wish found. - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function &GetLanguages() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - return $this->_languages; - } - - /*******************************************************************/ - /** \brief Accessor -Get a reference to the $_weekdays field. - - \returns a reference to the $_weekdays field. - The key is the weekday (1 = Sunday, 7 = Saturday), and the value is as follows: - - -1 NOT (exclude all meetings that occur on this weekday from the search). - - 0 No preference (This weekday will not be a consideration in the search). - - 1 Return meetings that occur on this weekday. - - Default is 0 for all. If no weekdays are specified (either 1 or -1), then the weekday will not be a - consideration in the meeting search. If any weekday is specified as 1, then ONLY meetings that occur on - the given weekday will be considered in the search, and you must explicitly set any other weekday you wish found. - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function &GetWeekdays() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - return $this->_weekdays; - } - - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function &GetVenueTypes() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - return $this->_venue_types; - } - - /*******************************************************************/ - /** \brief Accessor -Get a reference to the c_comdef_server object. - - \returns a reference to the c_comdef_server object instantiated by - this object. - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function GetServer() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - return $this->_my_server; - } - - /*******************************************************************/ - /** \brief Accessor -Get a reference to the root object. - - \returns a reference to the c_comdef_meeting_search_manager object. - If this is the root object, it will return a reference to itself. - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function GetRootObject() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $ret = null; - - if ($this->_my_root instanceof c_comdef_meeting_search_manager) { - $ret = $this->_my_root; - } else { - $ret = $this; - } - - return $ret; - } - - /*******************************************************************/ - /** \brief Set a search radius and center, with the Radius in miles. - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function SetSearchRadiusAndCenterInMiles( - $in_search_radius_in_miles, ///< The radius as specified in miles, not Km. - $in_long_in_degrees, ///< The longitude needs to be specified in degrees. - $in_lat_in_degrees ///< The latitude needs to be specified in degrees. - ) { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $this->SetSearchRadiusAndCenterInKm(1.609344 * $in_search_radius_in_miles, $in_long_in_degrees, $in_lat_in_degrees); - } - - /*******************************************************************/ - /** \brief Set a search radius and center, with the radius in Km. - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function SetSearchRadiusAndCenterInKm( - $in_search_radius_in_km, ///< The radius needs to be specified in kilometers, not miles. - $in_long_in_degrees, ///< The longitude needs to be specified in degrees. - $in_lat_in_degrees ///< The latitude needs to be specified in degrees. - ) { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $this->_search_radius = $in_search_radius_in_km; - $this->_search_center_long = $in_long_in_degrees; - $this->_search_center_lat = $in_lat_in_degrees; - } - - /*******************************************************************/ - /** \brief Set a search center, and a count for an auto radius hunt. - The way this works is that the center is set, and the optimal - radius is selected in kilometers to deliver that many meetings. - The radius starts at 25 Km (about 10 miles), and goes up or - down in 5Km "clicks." Under 5Km, it reduces to 0.5Km "clicks." - It will not go out more than 100Km. - - When it passes the threshold for the number of meetings in the - square, the radius is selected, and the _search_radius is set - to the number of Kilometers. - - We are not looking for an exact meeting count. It should select the - first radius that contains AT LEAST the number of meetings requested. - - If not enough meetings are found, the radius ends up at 0. - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function SetSearchRadiusAndCenterAuto( - $in_search_result_count, ///< A positive integer. It specifies the number of meetings to find. - $in_long_in_degrees, ///< The longitude needs to be specified in degrees. - $in_lat_in_degrees ///< The latitude needs to be specified in degrees. - ) { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $this->_search_radius_count = $in_search_result_count; - $this->_search_radius = 0; - $this->_search_center_long = $in_long_in_degrees; - $this->_search_center_lat = $in_lat_in_degrees; - } - - /*******************************************************************/ - /** \brief Get the search radius. - - \returns a floating-point number. If the $in_miles parameter is false, - the returned value is kilometers. If it is true, the returned value - is in miles. - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function GetRadius( - $in_miles = false ///< A boolean. If true, the returned value will be in miles. Otherwise, it is returned in kilometers. - ) { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - return $in_miles ? ($this->_search_radius / 1.609344) : $this->_search_radius; - } - - /*******************************************************************/ - /** \brief Get the longitude. - - \returns a floating-point number. The return is in degrees. - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function GetLongitude() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - return $this->_search_center_long; - } - - /*******************************************************************/ - /** \brief Get the latitude. - - \returns a floating-point number. The return is in degrees. - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function GetLatitude() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - return $this->_search_center_lat; - } - - /*******************************************************************/ - /** \brief Get the search for published value - - \returns an integer. - - -1 Search for ONLY unpublished meetings - - 0 Search for published and unpublished meetings. - - 1 Search for ONLY published meetings. - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function GetPublished() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - return $this->_published_search; - } - - /*******************************************************************/ - /** \brief Sets the search for published value - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function SetPublished( - $in_published_search - // The value to set. It can be: - // - -1 Search for ONLY unpublished meetings - // - 0 Search for published and unpublished meetings. - // - 1 Search for ONLY published meetings. - ) { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $this->_published_search = $in_published_search; - } - - /*******************************************************************/ - /** \brief Set a start time window. - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function SetStartTime( - $in_starts_after, ///< An epoch time, defining when the meeting should start (or after) - $in_starts_before = null ///< If defined, the meeting must start no later than this. - ) { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $this->_start_after = $in_starts_after; - - // We don't let this be less than, or equal to, the start time. - if ((null != $in_starts_after) && (null != $in_starts_before) - && (intval($in_starts_after) >= intval($in_starts_before))) { - $in_starts_before = null; - } - - // We don't let this be less than, or equal to, the start time. - if ((null != $in_starts_after) && (null != $in_starts_before) - && (intval($in_starts_after) >= intval($in_starts_before))) { - $in_starts_before = null; - } - - $this->_start_before = $in_starts_before; - } - - /*******************************************************************/ - /** \brief Set a maximum end time. - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function SetEndTime( - $in_ends_before ///< An epoch time, defining that the meeting must end no later than this. - ) { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $this->_end_before = $in_ends_before; - } - - /*******************************************************************/ - /** \brief Get the "ends before" value - - \returns an integer, containing the epoch time for the value. - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function GetEndsBefore() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - return $this->_end_before; - } - - /*******************************************************************/ - /** \brief Get the "starts after" value - - \returns an integer, containing the epoch time for the value. - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function GetStartTime_Min() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - return $this->_start_after; - } - - /*******************************************************************/ - /** \brief Get the "starts before" value - - \returns an integer, containing the epoch time for the value. - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function GetStartTime_Max() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - return $this->_start_before; - } - - /*******************************************************************/ - /** \brief Set a duration time window. - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function SetDuration( - $in_max_duration, ///< An epoch time, defining the maximum duration of a meeting. - $in_min_duration = null ///< If defined, the minimum duration of the meeting. - ) { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $this->_max_duration = $in_max_duration; - - // We don't let this be less than, or equal to, the start time. - if (((null != $in_max_duration) && (null != $in_min_duration)) && intval($in_min_duration) >= intval($in_max_duration)) { - $in_min_duration = null; - } - - $this->_min_duration = $in_min_duration; - } - - /*******************************************************************/ - /** \brief Get the Maximum Duration value - - \returns an integer, containing the epoch time for the value. - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function GetDuration_Max() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - return $this->_max_duration; - } - - /*******************************************************************/ - /** \brief Get the Minimum Duration value - - \returns an integer, containing the epoch time for the value. - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function GetDuration_Min() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - return $this->_min_duration; - } - - /*******************************************************************/ - /** \brief Set a search string. - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function SetSearchString( - $in_search_string, ///< A string. This is a string for which to search. - $in_all_words = false, ///< A Boolean. If this is true, then all of the words in a phrase must be present. - $in_literal = false ///< A Boolean. If this is true, then the spelling must be literal. - ) { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $this->_search_string = $in_search_string; - $this->_search_string_all_words = $in_all_words; - $this->_search_string_literal = $in_literal; - } - - /*******************************************************************/ - /** \brief Get the current search string. - - \returns a reference to the search string. - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function GetSearchString() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - return $this->_search_string; - } - - /*******************************************************************/ - /** \brief Set the current search string. - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function SetMeetingIDArray( - $in_meeting_id_array ///< An array of positive integers. These are the IDs of individual meetings to find. - ) { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $this->_meeting_id_array = $in_meeting_id_array; - } - - /*******************************************************************/ - /** \brief Get the current search string. - - \returns a reference to the meeting ID array. - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function GetMeetingIDArray() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - return $this->_meeting_id_array; - } - - /*******************************************************************/ - /** \brief Get the current search string "all words" flag. - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function StringSearchForAllWords() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - return $this->_search_string_all_words; - } - - /*******************************************************************/ - /** \brief Get the current search string literal flag. - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function StringSearchIsLiteral() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - return $this->_search_string_literal; - } - - /// These functions will help the caller to get information from the server. You can use them to build a search form. - - /*******************************************************************/ - /** \brief Returns an array of language enums and names. - - \returns a reference to an array of strings, containing the server - languages in human-readable, local form. The key will be the enum, - and the value will be the name of the language. - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function GetAvailableLanguages() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $ret = null; - - // Basic error checking. - if ($this->_my_server instanceof c_comdef_server) { - $ret = $this->_my_server->GetServerLangs(); - } - - return $ret; - } - - /*******************************************************************/ - /** \brief Returns an array of references to c_comdef_service_body objects. - - This returns ALL Service bodies; whether or not they contain meetings. - - \returns a reference to an array of c_comdef_service_body objects. - The key will be the ID of the Service body, and the value will be a reference - to the object. Null, if the function fails for any reason. - - This will reference the actual objects controlled by the server. - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function GetAvailableServiceBodies() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $ret = null; - - // Basic error checking. - if ($this->_my_server instanceof c_comdef_server) { - $ret = $this->_my_server->GetServiceBodyArray(); - } - - return $ret; - } - - /*******************************************************************/ - /** \brief Returns a multi-dimensional array of references to c_comdef_format objects. - - This returns ALL formats; whether or not they are used in meetings. - - \returns a reference to a multi-dimensional array of c_comdef_format objects. - The key will be the language enum, and the value will be another array, - which will have its key as the Shared ID of the format, and the value will be - a reference to the object. Null, if the function fails for any reason. - - This will reference the actual objects controlled by the server. - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function GetAvailableFormats() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $ret = null; - - // Basic error checking. - if ($this->_my_server instanceof c_comdef_server) { - // Start by getting the format aggregator object. - $formats_obj = $this->_my_server->GetFormatsObj(); - - if ($formats_obj instanceof c_comdef_formats) { - $ret = $formats_obj->GetFormatsArray(); - } - } - - return $ret; - } - - /*******************************************************************/ - /** \brief Returns an array of all possible field keys to be used for sorting. - - \returns an array of strings, with the key being the same as the value. - NOTE: This contains ALL possible keys, including ones that may not be - used in the found set. - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public static function GetAllAvailableSortKeys() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - return c_comdef_meeting::GetAllMeetingKeys(); - } - - /// These functions deal with the search itself. - - /*******************************************************************/ - /** \brief Returns an array of field keys to be used for sorting. - This function is not static, and searches the found set for keys. - As a result, it takes longer. - - \returns an array of strings, with the key being the same as the value. - NOTE: This contains only the keys used in this found set. - - As a result, this will return null until after a search has been performed. - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function GetSpecificSortKeys() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $ret = null; - - if ($this->_search_results instanceof c_comdef_meetings) { - $ret = $this->_search_results->GetMeetingKeys(); - } - - return $ret; - } - - /*******************************************************************/ - /** \brief Executes a new search. It will always force a new search. - - \returns an integer that indicates the number of meetings found. - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function DoSearch() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $this->GetSearchResults_Obj(true); - - $ret = $this->GetNumberOfResults(); - - return $ret; - } - - /*******************************************************************/ - /** \brief Returns a reference to the c_comdef_meetings object that - contains the results of the search. If this is null, or if the - $in_new_search parameter is set to true, the search will be - executed, otherwise, this just returns a reference to the existing - search results. - - \returns a reference to the internal $_search_results field (an - instance of c_comdef_search_results). - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function GetSearchResults_Obj( - $in_new_search = false ///< If this is set to true, the search is done anew. - ) { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - // See if we need to make a new search. Only the root can do a new search. - if ((null == $this->_my_root) && (true == $in_new_search) || (null == $this->_search_results)) { - $this->_search_results = null; - - // Basic error checking. - if ($this->_my_server instanceof c_comdef_server) { - // If we have an ID array, then we skip everything else, and just search for those IDs. - if (is_array($this->_meeting_id_array) && count($this->_meeting_id_array)) { - $this->_search_results = c_comdef_server::GetMeetingsByID($this->_meeting_id_array); - - if ($this->_search_results instanceof c_comdef_meetings) { - $this->_search_results->RemoveInvalidMeetings(); - - // Force a new sort. - $this->SortMeetingObjects(); - } - } else { - // We start by specifying a search using the main criteria. We need to interpret the current state into search criteria. - - // Set up our Service Bodies Array. - $service_bodies = null; - - if (is_array($this->_service_bodies) && count($this->_service_bodies)) { - $service_bodies = array(); - foreach ($this->_service_bodies as $key => $value) { - // If the value of the Service Body is 1 or -1, we add it to the list. - if (abs($value) == 1) { - array_push($service_bodies, intval($key) * $value); - } - } - } - - // Set up our weekday array. - $weekdays = null; - - if (is_array($this->_weekdays) && count($this->_weekdays)) { - $weekdays = array(); - foreach ($this->_weekdays as $key => $value) { - // If the value of the Weekday is 1 or -1, we add it to the list. - if (abs($value) != 0) { - array_push($weekdays, intval($key) * $value); - } - } - } - - // Venue Types - $venueTypes = null; - if (is_array($this->_venue_types) && count($this->_venue_types)) { - $venueTypes = array(); - foreach ($this->_venue_types as $key => $value) { - if (abs($value) != 0) { - // I have no idea why we are multiplying here... just following the pattern - array_push($venueTypes, intval($key) * $value); - } - } - } - - // Set up our formats array. - $formats = null; - - if (is_array($this->_formats) && count($this->_formats)) { - $formats = array(); - foreach ($this->_formats as $key => $value) { - // If the value of the format is 1 or -1, we add it to the list. - if (abs($value) == 1) { - array_push($formats, intval($key) * $value); - } - } - } - - $languages = null; - - if (is_array($this->_languages) && count($this->_languages)) { - $languages = array(); - foreach ($this->_languages as $key => $value) { - // If the value of the format is 1 or -1, we add it to the list. - if (abs($value) == 1) { - array_push($languages, ($value == -1) ? "-$key" : $key); - } - } - } - - // If we will specify a search radius, we specify a restricted area for the search. - $search_rect = $this->GetSquareForRadius($weekdays, $service_bodies); - - // Do the main database search first. - $null_me = null; - $this->_search_results = c_comdef_server::GetMeetings( - $service_bodies, - $languages, - $weekdays, - $venueTypes, - $formats, - $this->_start_after, - $this->_start_before, - $this->_end_before, - $this->_min_duration, - $this->_max_duration, - $search_rect, - null, - $null_me, - $this->_published_search, - $this->_formats_comparison_operator - ); - if (isset($this->_search_results) && $this->_search_results && ($this->_search_results instanceof c_comdef_meetings)) { - $this->_search_results->RemoveInvalidMeetings(); - - // Force a new sort. - $this->SortMeetingObjects(); - - // These are two "post-database" searches that we do. - if (null != $this->_search_radius) { - $this->_search_results = $this->_search_results->GetMeetingsByDistance($this->_search_center_long, $this->_search_center_lat, $this->_search_radius, true, $this->_sort_search_by_distance); - } - - if (null != $this->_search_string) { - $_search_results = $this->_search_results->GetMeetingsByString($this->_search_string, null, $this->_search_string_all_words, $this->_search_string_literal); - $this->_search_results = null; - $this->_search_results = $_search_results; - } - - if ($this->_meeting_key) { - $key_array = (is_array($this->_meeting_key) && count($this->_meeting_key)) ? $this->_meeting_key : array ( $this->_meeting_key ); - $_search_results = $this->_search_results->GetMeetingsByKeyValue($key_array, $this->_meeting_key_value, $this->_meeting_key_contains, $this->_meeting_key_match_case); - $this->_search_results = null; - $this->_search_results = $_search_results; - } - } - } - } - } - - return $this->_search_results; - } - - /*******************************************************************/ - /** \brief Clears the search results, so the next access will redo the search. - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function ClearSearch() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - // Only the root can clear its search results. - if (null == $this->_my_root) { - $this->_search_results = null; - } - } - - /*******************************************************************/ - /** \brief This will return the search results as an array of c_comdef_meeting - objects. - - \returns a reference to an array of references to c_comdef_meeting objects. - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function GetSearchResultsAsArray() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $ret = null; - - if ($this->GetSearchResults_Obj() instanceof c_comdef_meetings) { - $s_array = $this->GetSearchResults_Obj()->GetMeetingObjects(); - - if (is_array($s_array) && count($s_array)) { - $ret = $s_array; - } - } - - return $ret; - } - - /// These are sorting functions. - - /*******************************************************************/ - /** \brief Simply clears out the sort array, so the search is unsorted. - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function ClearSort() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - // Only the root can do this. - if (null == $this->_my_root) { - $this->sort_array = null; - } - } - - /*******************************************************************/ - /** \brief Accessor. Set the maximum number of sorts to maintain. - If the current number is more than the new value, then we remove any - beyond that. - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function SetSortDepth( - $in_new_depth = 0 ///< A positive integer. If nothing is provided, we set to endless (0). - ) { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - // Only the root can do this. - if (null == $this->_my_root) { - $this->sort_depth = $in_new_depth; - if (0 < $this->sort_depth) { // Only if a depth is defined. - while (count($this->sort_array) > $this->sort_depth) { - array_shift($this->sort_array); // Take off the bottommost one. - } - } - - // Force a new sort, based on the new depth. - $this->SortMeetingObjects(); - } - } - - /*******************************************************************/ - /** \brief Set a new "top" sort priority. - - The prior "top" sort priority will be made secondary. If the key - was previously "lower" in the sort priority, it is removed from there. - - It will trigger a sort after the new key has been established. - - This allows a very "natural" type of sorting, where the user goes - from one field to another. - - This will always reset the sort direction to the given one (or will - reset to ascending). We could save the direction with each column, - but that is likely to result in a confusing mess. It's a better idea - to just apply the same direction to every column. - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function SetTopSortPriority( - $in_new_top_sort_key, ///< A string. This should be the database table column name for the new "top" sort key. - $in_desc = false ///< If this is set to true, the sort will be highest to lowest. Default is false. - ) { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - // Only the root can do this. - if (null == $this->_my_root) { - // We first remove any previous mention of this key. - for ($i = 0; $i < count($this->sort_array); $i++) { - if ($this->sort_array[$i] == $in_new_top_sort_key) { - unset($this->sort_array[$i]); - break; - } - } - - // The new key goes in as the first item. - if (!is_array($this->sort_array) || (1 > count($this->sort_array))) { - $this->sort_array = array( $in_new_top_sort_key ); - } else { - // We first see if we are at the limit for sort depth. - - if (0 < $this->sort_depth) { // Only if a depth is defined. - while (count($this->sort_array) >= $this->sort_depth) { - array_shift($this->sort_array); // Take off the bottommost one. - } - } - - array_unshift($this->sort_array, $in_new_top_sort_key); - } - - // Make sure the new array direction is recorded. - $this->sort_desc = $in_desc; - - // Force a new sort. - $this->SortMeetingObjects(); - } - } - - /*******************************************************************/ - /** \brief Sets up the sort array and direction. This replaces the - entire array and direction. If the array is longer than the - maximum number of sort keys, only that number of keys are used. - - It will reset the sort direction, so you need to explicitly indicate - the sort direction if you want it descending, as opposed to ascending. - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function SetSort( - $in_sort_fields_array = null, - // An array of strings. The array will deliniate the sort order, by field name. - // Array element [0] will be the highest priority, and it will descend from there. - // If this is not specified, the sort will be cleared. - $in_desc = false, ///< If this is set to true, the sort will be highest to lowest. Default is false. - $in_max_sort_keys = 0 ///< A positive integer, specifying a new maximum sort depth. If it is not specified, the max will not be changed. - ) { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - // Only the root can do this. - if (null == $this->_my_root) { - if (false != $in_desc) { - $in_desc = true; - } - - $this->sort_desc = $in_desc; - - if (0 < $in_max_sort_keys) { - $this->sort_depth = $in_max_sort_keys; - } - - if (null != $in_sort_fields_array) { - $max = min($this->sort_depth, count($in_sort_fields_array)); - - if ($max > 0) { - $this->sort_array = array_slice($in_sort_fields_array, 0, $max); - } else { - $this->sort_array = null; - } - } - } - } - - /*******************************************************************/ - /** \brief Sorts the meetings. - This will apply a sort, dependent upon the given fields. - The given array contains the field names (SQL columns and keys) - for the data to be sorted. - - If you don't specify any parameters, the ones from the last sort - will be used. - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function SortMeetingObjects( - $in_sort_fields_array = null, - // An array of strings. The array will deliniate the sort order, by field name. - // Array element [0] will be the highest priority, and it will descend from there. - $in_desc = null ///< If this is set to true, the sort will be highest to lowest. Default is false. - ) { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - // Only the root can do this. - if (null == $this->_my_root) { - if (null != $this->_search_results) { - if (null != $in_sort_fields_array) { - $this->sort_array = $in_sort_fields_array; - } else { - $in_sort_fields_array = $this->sort_array; - } - - if (null != $in_desc) { - $this->sort_desc = $in_desc; - } else { - $in_desc = $this->sort_desc; - } - - if (is_array($in_sort_fields_array) && count($in_sort_fields_array)) { - // This is simply a "pass-through" to the object we have on hand. - $this->_search_results->SortMeetingObjects($in_sort_fields_array, $in_desc, $this->_sort_search_by_distance); - } - } - } - } - - /// These are various utility functions. - - /*******************************************************************/ - /** \brief This is an internal utility function that takes a specified - radius and center point and calculates a square, in longitude and - latitude points, that encompasses that radius. This greatly narrows - the scope of the search, so the radius calculation will simply eliminate - any meetings that are "in the corners." - - If the setting is for auto-radius, the auto-radius is first resolved, then - the main radius value is set. Remember that auto-radius is for all meetings, - all days of the week. It is really a "density test," as opposed to an - accurate selector. - - \returns an array of floating-point values, in the following form: - - ['east'] = longitude of the Eastern side of the rectangle - - ['west'] = longitude of the Western side of the rectangle - - ['north'] = latitude of the Northern side of the rectangle - - ['south'] = latitude of the Southern side of the rectangle - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function GetSquareForRadius( - $in_weekday_tinyint_array, ///< An array of weekdays in which to filter for. - $in_service_bodies_array = null ///< An array of service bodies in which to filter for. - ) { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $loc = array (); - - if ($this->_search_radius_count) { - $this->_search_radius = c_comdef_server::HuntForRadius($this->_search_radius_count, $this->_search_center_long, $this->_search_center_lat, $in_weekday_tinyint_array, $in_service_bodies_array); - $this->_search_radius_count = null; - } - - if ($this->_search_radius > 0) { - $loc = c_comdef_server::GetSquareForRadius($this->_search_radius, $this->_search_center_long, $this->_search_center_lat); - } - - return $loc; - } - - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function SetFormatsComparisonOperator($operator) - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - if ($operator == "OR") { - $this->_formats_comparison_operator = "OR"; - } else { - $this->_formats_comparison_operator = "AND"; - } - } - - /// These are static functions for directly accessing meetings via ID. - - /*******************************************************************/ - /** \brief This is a static utility function that will return one single - instance of c_comdef_meeting, based upon the ID of that meeting. - - \returns a new (not reference) c_comdef_meeting instance. Null if it fails. - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public static function GetSingleMeetingByID( - $in_id ///< An integer. The ID of the meeting. - ) { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - return c_comdef_server::GetOneMeeting($in_id); - } - - /*******************************************************************/ - /** \brief This is a static utility function that will return multiple - instances of c_comdef_meeting, based upon the IDs of the meetings. - It will create an array to hold these instances - - NOTE: This is NOT the same as the c_comdef_server::GetMeetingsByID() - function, as that function returns an instance of c_comdef_meetings. - - \returns an array of new (not reference) c_comdef_meeting instances. - Null if it fails. - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public static function GetMultipleMeetingsByID( - $in_id_array ///< An array of integers. The IDs of the meetings. - ) { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $ret = null; - - if (is_array($in_id_array) && count($in_id_array)) { - foreach ($in_id_array as $id) { - $ret[$id] = c_comdef_search_manager::GetSingleMeetingByID($id); - } - } - - return $ret; - } -} diff --git a/src/legacy/client_interface/csv/common_search.inc.php b/src/legacy/client_interface/csv/common_search.inc.php deleted file mode 100755 index 1a9fbaa7d..000000000 --- a/src/legacy/client_interface/csv/common_search.inc.php +++ /dev/null @@ -1,779 +0,0 @@ -. -*/ - -/*******************************************************************/ -/** \brief This function sets up the search manager to do the specified - search. It does not actually do the search. -*/ -function SetUpSearch( - &$in_search_manager, ///< A reference to an instance of c_comdef_search_manager. The search manager to set up. - &$in_http_vars - // The various HTTP GET and POST parameters. - // The values that are important to the search are: - // - 'services' - // This is an array of positive integers. - // This is interpreted as an array of integers. Each integer represents the ID of a Service Body. - // A positive integer means that the search will look specifically for meetings that contain that - // Service Body ID. - // If the integer is negative (preceded by a minus sign -), then the criteria will be to look - // for meetings that don't contain that ID. - // If no 'services' values are given, then the search will not use the Service Body field as a - // search criteria. - // - // - 'recursive' - // If this is set to '1', then the 'services' key will recursively follow Service bodies. - // - // - 'venue_types' - // This is an array of integers. - // This is interpreted as an array of integers. Each integer represents a Venue Type. - // A positive integer means that the search will look specifically for meetings that have that Venue Type. - // If the integer is negative (preceded by a minus sign -), then the criteria will be to look - // for meetings that don't have that Venue Type. - // If no 'venue_type' values are given, then the search will not use the Venue Type field as a - // search criteria. - // - // - 'weekdays' - // This is an array of negative or positive nonzero integers (-7 - -1, 1 - 7). - // This is interpreted as an array of integers. Each integer represents a weekday (1 -> Sunday, 7 -> Saturday). - // A positive integer means that the search will look specifically for meetings that occur on that weekday. - // If the integer is negative (preceded by a minus sign -), then the criteria will be to look - // for meetings that don't occur on that weekday. - // If no 'weekdays' values are given, then the search will not use the weekday field as a - // search criteria. - // - // - 'bmlt_search_type' - // This is set to 'advanced' if the search is an advanced one (we need to take more criteria into consideration). - // - // - 'advanced_search_mode' - // This is set if the call was made from the advanced search page. - // - // - 'advanced_formats' - // This is the formats array, but is only counted if the bmlt_search_type is set to 'advanced'. - // - // - 'advanced_service_bodies' - // This is the same, but for Service Bodies. - // - // - 'advanced_weekdays' - // ...and weekdays. - // - // - 'advanced_radius' - // ...and radius (in degrees) - // - // - advanced_mapmode - // If this is true (1), then the Advanced form is using its map. - // - // - 'advanced_published' - // This is a switch to indicate whether or not to display published or unpublished meetings. - // It is only viable for logged-in users, and can have these values: - // - -1 Search for ONLY unpublished meetings - // - 0 Search for published and unpublished meetings. - // - 1 Search for ONLY published meetings. - // - // - 'formats' - // This is an array of positive integers. - // This is interpreted as an array of integers. Each integer represents a format shared ID. - // A format ID means that the search will look specifically for meetings that have that format. - // If the format is negative (preceded by a minus sign -), then the criteria will be to look - // for meetings that don't have that format. - // If no 'formats' values are given, then the search will not use the formats field as a - // search criteria. - // - // - 'formats_comparison_operator' - // This is a string used to set the operator used to compare included (positive integer) formats. Valid values - // and AND and OR. - // - // - 'langs' - // This is an array of 2-character strings. - // This is interpreted as an array of strings. Each string represents a language code, and is a 2-character string. - // A language string means that the search will look specifically for meetings that are in that language. - // If the language is preceded by a minus sign -, then the criteria will be to look - // for meetings that are not in that language. - // If no 'langs' values are given, then the search will not use the lang_enum field as a - // search criteria. - // - // The following values specify a start time "window." The meeting must start on, or after StartsAfterH/M, and - // can start no later than StartsBeforeH/M - // - // - 'StartsAfterH' - // A positive integer between 0 and 23. The hour of the minimal start time for meetings, in military time. - // - 'StartsAfterM' - // A positive integer between 0 and 59. The minute of the minimal start time for meetings, in military time. - // - 'StartsBeforeH' - // A positive integer between 0 and 23. The hour of the maximal start time for meetings, in military time. - // - 'StartsBeforeM' - // A positive integer between 0 and 59. The minute of the maximal start time for meetings, in military time. - // - // The following values specify a time duration "window." The meeting can last no longer than MaxDurationH/M, - // and no less than MinDurationH/M. - // - // - 'MinDurationH' - // A positive integer. This is the number of hours in the minimal duration. - // - 'MinDurationM' - // A positive integer. This is the number of minutes in the minimal duration. - // - 'MaxDurationH' - // A positive integer. This is the number of hours in the maximal duration. - // - 'MaxDurationM' - // A positive integer. This is the number of minutes in the maximal duration. - // - // This is how meetings are located. We don't use address lookups. Instead, we geolocate the meetings via the - // longitude and latitude fields in each record. If you don't specify a geolocation, then the entire database - // is searched. If you do specify one, then only the portion within the radius is searched. - // - // - 'geo_width' - // A floating point number. This is the radius (not diameter) of the search, in MILES (not Kilometers). - // If this is negative, then it should be an integer, and that indicates an auto-radius is requested to - // find the number of meetings in the integer. - // - // - 'geo_width_km' - // A floating point number. This is the radius (not diameter) of the search, in KILOMETERS (not Miles). - // If this is negative, then it should be an integer, and that indicates an auto-radius is requested to - // find the number of meetings in the integer. - // - // - 'long_val' - // If one of the three radius specifiers is zero or undefined, this is ignored. - // This is a floating point number that specifies the longitude, in degrees, of the center of the search radius. - // - // - 'lat_val' - // If one of the three radius specifiers is zero or undefined, this is ignored. - // This is a floating point number that specifies the latitude, in degrees, of the center of the search radius. - // - // - 'SearchString' - // A string. If this is specified, then all the string fields of the meetings specified by the above criteria - // will be searched for the string. By default, if the language supports metaphone (sound like search), then - // that is used. - // - // - 'StringSearchIsAnAddress' - // A boolean. Nonzero means that the given string should not be checked against any of the fields in the meeting - // data. Instead, it is to be considered a submission to the Google Maps geocode, and will be used to determine - // a cernter point in a local search. - // - // - 'SearchStringAll' - // If nonzero, then all of the words in the search string will have to be matched for a meetings to qualify. - // - // - 'SearchStringExact' - // If nonzero, metaphone will not be used, and the spelling must be exact. - // - // - 'SearchStringRadius' - // If specified, the radius of the search around the address (ignored if StringSearchIsAnAddress is false). - // The units are in whatever the server units are for this language (can be miles or kilometers). - // Negative numbers must always be integers, and specify a rough target number of meetings for auto-radius. - // - // - 'meeting_ids' - // An array of positive integers. Each integer is an ID of an individual meeting. If this is set, all other - // search criteria are ignored. - // - // - 'meeting_key' - // A string. This is the exact name of the key to match. If this is null (Default), the following three are ignored. - // NOTE: As of 1.5, the behavior of this field has changed. - // If it is an array, then the string search is done via metaphone, unless meeting_key_match_case is true. - // If it is an array, then the search is done on all the fields in the array, assuming they are all text. - // Non-string fields are ignored. - // - // - 'meeting_key_value' - // A string. The value to match. - // NOTE: As of Version 1.5, this is matched with a metaphone match, as well as the RegEx match. - // - // - 'meeting_key_match_case' - // If true, the case must match. Default is false. - // NOTE: As of Version 1.5, setting this to TRUE also stops the metaphone search. - // - // - 'meeting_key_contains' - // If this is true, then the string can have partial matches. Default is false (literal). - // - // - 'sort_results_by_distance' - // If this is true, then, if possible, the search results will be sorted by distance from the radius center. - // If this is set, then the 'sort_keys' parameter below will be ignored. - // - // - 'sort_keys' - // This is a comma-separated list of sort keys. The leftmost one will be the top priority, and the rightmost the lowest. - // The sort depth will be the number of keys. - // The direction will be assumed 'asc', unless 'desc' is one of the keys (it can be anywhere in the list). -) { - $search_string = isset($in_http_vars['SearchString']) ? trim($in_http_vars['SearchString']) : ''; - - if ($search_string && !(isset($in_http_vars['StringSearchIsAnAddress']) && $in_http_vars['StringSearchIsAnAddress']) && intval($search_string) && (preg_match('|\d+|', $search_string) || preg_match('(|\d+|,)+', $search_string))) { - $temp_ids = explode(',', $search_string); - - if (is_array($temp_ids) && count($temp_ids)) { - $first = true; - - foreach ($temp_ids as $id) { - $id = intval(trim($id)); - - if ($id) { - if ($first) { - $in_http_vars['meeting_ids'] = null; - $first = false; - } - - $in_http_vars['meeting_ids'][] = $id; - } - } - } else { - $id = intval($search_string); - - if ($id) { - $in_http_vars['meeting_ids'] = array ( intval($id) ); - } - } - } - - // If we have a meeting ID array, then that defines the entire search. We ignore everything else - if (isset($in_http_vars['meeting_ids']) && is_array($in_http_vars['meeting_ids']) && count($in_http_vars['meeting_ids'])) { - $in_search_manager->SetMeetingIDArray($in_http_vars['meeting_ids']); - } else { - if (isset($in_http_vars['sort_results_by_distance'])) { - $in_search_manager->SetSortByDistance($in_http_vars['sort_results_by_distance']); - } elseif (isset($in_http_vars['sort_keys']) && $in_http_vars['sort_keys']) { - $sort_fields = array(); - $keys = explode(',', $in_http_vars['sort_keys']); - $dir = 'asc'; - foreach ($keys as $key) { - if (strtolower(trim($key)) == 'desc') { - $dir = 'desc'; - } else { - $templates = c_comdef_meeting::GetDataTableTemplate(); - if ($templates && count($templates)) { - $additional = array (); - - foreach ($templates as $template) { - $value = $template['key']; - array_push($additional, $value); - } - - $standards = array ( 'weekday_tinyint', 'venue_type', 'id_bigint', 'worldid_mixed', 'service_body_bigint', 'lang_enum', 'duration_time', 'start_time', 'longitude', 'latitude' ); - $templates = array_merge($standards, $additional); - - if (in_array($key, $templates)) { - array_push($sort_fields, $key); - } - } - } - } - - $in_search_manager->SetSort($sort_fields, $dir == 'desc', count($sort_fields)); - } - - // The first thing we do is try to resolve any address lookups. - if ($search_string && isset($in_http_vars['StringSearchIsAnAddress']) && $in_http_vars['StringSearchIsAnAddress']) { - $geo_search = (isset($in_http_vars['geo_width']) && $in_http_vars['geo_width']) ? true : ((isset($in_http_vars['geo_width_km']) && $in_http_vars['geo_width_km']) ? true : false); - - // We do a geocode to find out if this is an address. - if (!$geo_search) { - $search_string = preg_replace('|,(\s*?)|', ', ', $search_string); // This works around a bug caused by too-tight commas. - $geo = GetGeocodeFromString($search_string, $in_http_vars['advanced_weekdays'] ?? null); - if (is_array($geo) && count($geo)) { - $localized_strings = c_comdef_server::GetLocalStrings(); - - $in_http_vars['long_val'] = $geo['longitude']; - $in_http_vars['lat_val'] = $geo['latitude']; - - if (isset($in_http_vars['SearchStringRadius']) && floatval($in_http_vars['SearchStringRadius']) != 0.0) { - if (intval($in_http_vars['SearchStringRadius']) < 0) { - $geo['radius'] = intval($in_http_vars['SearchStringRadius']); - } else { - $geo['radius'] = floatval($in_http_vars['SearchStringRadius']); - } - } - - if ($localized_strings['dist_units'] == 'mi') { - if (isset($in_http_vars['geo_width_km'])) { - unset($in_http_vars['geo_width_km']); - } - $in_http_vars['geo_width'] = $geo['radius']; - } else { - unset($in_http_vars['geo_width']); - $in_http_vars['geo_width_km'] = $geo['radius']; - } - - /* We need to undef these, because they can step on the long/lat. */ - unset($search_string); - unset($in_http_vars['StringSearchIsAnAddress']); - unset($in_http_vars['SearchStringRadius']); - } - } - } - - // First, set up the services. - if (isset($in_http_vars['bmlt_search_type']) && ($in_http_vars['bmlt_search_type'] == 'advanced') && isset($in_http_vars['advanced_service_bodies']) && is_array($in_http_vars['advanced_service_bodies']) && count($in_http_vars['advanced_service_bodies'])) { - $in_http_vars['services'] = $in_http_vars['advanced_service_bodies']; - } - - if (isset($in_http_vars['services']) && !is_array($in_http_vars['services'])) { - $in_http_vars['services'] = array ( $in_http_vars['services'] ); - } - - // Look for Service bodies. - if (isset($in_http_vars['services']) && is_array($in_http_vars['services']) && count($in_http_vars['services'])) { - $services = array(); - - if (isset($in_http_vars['recursive']) && $in_http_vars['recursive']) { - foreach ($in_http_vars['services'] as $service) { - $nested = GetAllContainedServiceBodyIDs(intval($service)); - - if (isset($nested) && is_array($nested) && count($nested)) { - foreach ($nested as $sb_i) { - $sb_i = intval($sb_i); - $services[$sb_i] = $sb_i; - } - } - } - } else { - $services = $in_http_vars['services']; - } - - $sb =& $in_search_manager->GetServiceBodies(); - - foreach ($services as $service) { - $sb[intval($service)] = 1; - } - } else { - unset($in_http_vars['services']); - } - - if (!( isset($in_http_vars['geo_width_km']) && $in_http_vars['geo_width_km'] ) - && !( isset($in_http_vars['geo_width']) && $in_http_vars['geo_width'] ) - && isset($in_http_vars['bmlt_search_type']) - && ($in_http_vars['bmlt_search_type'] == 'advanced') - && isset($in_http_vars['advanced_radius']) - && isset($in_http_vars['advanced_mapmode']) - && $in_http_vars['advanced_mapmode'] - && ( floatval($in_http_vars['advanced_radius'] != 0.0) ) - && isset($in_http_vars['lat_val']) - && isset($in_http_vars['long_val']) - && ( (floatval($in_http_vars['lat_val']) != 0.0) || (floatval($in_http_vars['long_val']) != 0.0) ) - ) { - if ($localized_strings['dist_units'] == 'mi') { - $in_http_vars['geo_width'] = $in_http_vars['advanced_radius']; - unset($in_http_vars['geo_width_km']); - } else { - $in_http_vars['geo_width_km'] = $in_http_vars['advanced_radius']; - unset($in_http_vars['geo_width']); - } - } - - // If we aren't doing any geographic searches, then we won't have a search center. - if (!( isset($in_http_vars['geo_width']) && $in_http_vars['geo_width'] ) && !( isset($in_http_vars['geo_width_km']) && $in_http_vars['geo_width_km'] )) { - unset($in_http_vars['lat_val']); - unset($in_http_vars['long_val']); - } - - // Next, set up the weekdays. - if (isset($in_http_vars['bmlt_search_type']) && ($in_http_vars['bmlt_search_type'] == 'advanced') && isset($in_http_vars['advanced_weekdays']) && ((is_array($in_http_vars['advanced_weekdays']) && count($in_http_vars['advanced_weekdays'])) || isset($in_http_vars['advanced_weekdays']))) { - $in_http_vars['weekdays'] = $in_http_vars['advanced_weekdays']; - } - - if (isset($in_http_vars['weekdays']) && !is_array($in_http_vars['weekdays']) && (intval(abs($in_http_vars['weekdays'])) > 0) && (intval(abs($in_http_vars['weekdays'])) < 8)) { - $in_http_vars['weekdays'] = array ( intval($in_http_vars['weekdays']) ); - } - - if (isset($in_http_vars['weekdays']) && is_array($in_http_vars['weekdays']) && count($in_http_vars['weekdays'])) { - $wd =& $in_search_manager->GetWeekdays(); - foreach ($in_http_vars['weekdays'] as $weekday) { - $wd[abs(intval($weekday))] = intval($weekday) > 0 ? 1 : -1; - } - } elseif (isset($in_http_vars['weekdays'])) { - $wd =& $in_search_manager->GetWeekdays(); - $wd[abs(intval($in_http_vars['weekdays']))] = intval(intval($in_http_vars['weekdays'])) > 0 ? 1 : -1; - } - - // Venue Types - if (isset($in_http_vars['venue_types']) && is_array($in_http_vars['venue_types']) && count($in_http_vars['venue_types'])) { - $vt =& $in_search_manager->GetVenueTypes(); - foreach ($in_http_vars['venue_types'] as $venueType) { - $vt[abs(intval($venueType))] = intval($venueType) > 0 ? 1 : -1; - } - } else if (isset($in_http_vars['venue_types'])) { - $vt =& $in_search_manager->GetVenueTypes(); - $vt[abs(intval($in_http_vars['venue_types']))] = intval($in_http_vars['venue_types']) > 0 ? 1 : -1; - } - - // Next, set up the formats. - if (isset($in_http_vars['bmlt_search_type']) && ($in_http_vars['bmlt_search_type'] == 'advanced') && isset($in_http_vars['advanced_formats']) && is_array($in_http_vars['advanced_formats']) && count($in_http_vars['advanced_formats'])) { - $in_http_vars['formats'] = $in_http_vars['advanced_formats']; - } - - if (isset($in_http_vars['formats'])) { - if (!is_array($in_http_vars['formats'])) { - $in_http_vars['formats'] = array ( intval($in_http_vars['formats']) ); - } - - $fm =& $in_search_manager->GetFormats(); - foreach ($in_http_vars['formats'] as $format) { - $key = abs(intval($format)); - $fm[$key] = (intval($format) > 0) ? 1 : -1; - } - } - - if (isset($in_http_vars['formats_comparison_operator']) && $in_http_vars['formats_comparison_operator'] == "OR") { - $in_search_manager->SetFormatsComparisonOperator("OR"); - } - - // Next, set up the languages. - if (isset($in_http_vars['langs']) && is_array($in_http_vars['langs']) && count($in_http_vars['langs'])) { - $lan =& $in_search_manager->GetLanguages(); - foreach ($in_http_vars['langs'] as $lng) { - $lan[$lng] = 1; - } - } - - // Next, set up the advanced published option. - if (isset($in_http_vars['advanced_published'])) { - $in_search_manager->SetPublished(intval($in_http_vars['advanced_published'])); - } else { - $in_search_manager->SetPublished(1); - } - - // Set the start window. - $start_time = null; - $end_time = null; - - // Next, the minimum start time.. - if (isset($in_http_vars['StartsAfterH']) || isset($in_http_vars['StartsAfterM'])) { - $start_hour = min(23, max(0, intval($in_http_vars['StartsAfterH']))); - $start_minute = min(59, max(0, intval($in_http_vars['StartsAfterM']))); - $start_time = mktime($start_hour, $start_minute); - } - - // Next, the maximum start time.. - if (isset($in_http_vars['StartsBeforeH']) || isset($in_http_vars['StartsBeforeM'])) { - $end_hour = min(23, max(0, intval($in_http_vars['StartsBeforeH']))); - $end_minute = min(59, max(0, intval($in_http_vars['StartsBeforeM']))); - $end_time = mktime($end_hour, $end_minute); - } - - $in_search_manager->SetStartTime($start_time, $end_time); - - $end_time = null; - - // Next, the maximum end time.. - if (isset($in_http_vars['EndsBeforeH']) || isset($in_http_vars['EndsBeforeM'])) { - $end_hour = min(23, max(0, intval($in_http_vars['EndsBeforeH']))); - $end_minute = min(59, max(0, intval($in_http_vars['EndsBeforeM']))); - $end_time = ($end_hour * 3600) + ($end_minute * 60); - } - - $in_search_manager->SetEndTime($end_time); - - // Set the duration window. - $max_duration_time = null; - $min_duration_time = null; - - // Next, the minimum start time.. - if (isset($in_http_vars['MaxDurationH']) || isset($in_http_vars['MaxDurationM'])) { - $max_duration_hour = min(23, max(0, intval($in_http_vars['MaxDurationH']))); - $max_duration_minute = min(59, max(0, intval($in_http_vars['MaxDurationM']))); - $max_duration_time = mktime($max_duration_hour, $max_duration_minute); - } - - // Next, the maximum start time.. - if (isset($in_http_vars['MinDurationH']) || isset($in_http_vars['MinDurationM'])) { - $min_duration_hour = min(23, max(0, intval($in_http_vars['MinDurationH']))); - $min_duration_minute = min(59, max(0, intval($in_http_vars['MinDurationM']))); - $min_duration_time = mktime($min_duration_hour, $min_duration_minute); - } - - $in_search_manager->SetDuration($max_duration_time, $min_duration_time); - - // Next, we deal with a geolocated search radius. - - if ((isset($in_http_vars['geo_width']) && ($in_http_vars['geo_width'] != 0)) - || (isset($in_http_vars['geo_width_km']) && ($in_http_vars['geo_width_km'] != 0) )) { - $long = isset($in_http_vars['long_val']) ? floatval($in_http_vars['long_val']) : 0; - $lat = isset($in_http_vars['lat_val']) ? floatval($in_http_vars['lat_val']) : 0; - $radius_in_miles = 0; - $radius_in_km = 0; - $local_strings = c_comdef_server::GetLocalStrings(); - $radius_auto = $local_strings['number_of_meetings_for_auto']; - - if (isset($in_http_vars['geo_width']) && ( $in_http_vars['geo_width'] != 0 )) { - if ($in_http_vars['geo_width'] < 0) { - $radius_auto = 0 - intval($in_http_vars['geo_width']); - } else { - $radius_in_miles = floatval($in_http_vars['geo_width']); - } - } elseif (isset($in_http_vars['geo_width_km']) && ( $in_http_vars['geo_width_km'] != 0 )) { - if ($in_http_vars['geo_width_km'] < 0) { - $radius_auto = 0 - intval($in_http_vars['geo_width_km']); - } else { - $radius_in_km = floatval($in_http_vars['geo_width_km']); - } - } - - if ($radius_in_miles > 0) { - $in_search_manager->SetSearchRadiusAndCenterInMiles($radius_in_miles, $long, $lat); - } elseif ($radius_in_km > 0) { - $in_search_manager->SetSearchRadiusAndCenterInKm($radius_in_km, $long, $lat); - } elseif ($radius_auto > 0) { - $in_search_manager->SetSearchRadiusAndCenterAuto($radius_auto, $long, $lat); - } - } - - if (isset($search_string) && (!isset($in_http_vars['meeting_key']) || !(is_array($in_http_vars['meeting_key']) && count($in_http_vars['meeting_key'])))) { - // And last, but not least, a string search: - $find_all = (isset($in_http_vars['SearchStringAll']) && $in_http_vars['SearchStringAll']) ? true :false; - $literal = (isset($in_http_vars['SearchStringExact']) && $in_http_vars['SearchStringExact']) ? true :false; - $in_search_manager->SetSearchString($search_string, $find_all, $literal); - } - - if (isset($in_http_vars['meeting_key']) && $in_http_vars['meeting_key']) { - // This is true by default. - if (!isset($in_http_vars['meeting_key_contains'])) { - $in_http_vars['meeting_key_contains'] = false; - } - - // This is false by default. - if (!isset($in_http_vars['meeting_key_match_case'])) { - $in_http_vars['meeting_key_match_case'] = false; - } - $in_search_manager->SetKeyValueSearch($in_http_vars['meeting_key'], $in_http_vars['meeting_key_value'], $in_http_vars['meeting_key_match_case'], $in_http_vars['meeting_key_contains']); - } - } -} - -/*******************************************************************/ -/** \brief This gets all the Service bodies, and returns a one-dimensional - arry, containing its ID, and the IDs of all the Service bodies - that are contained in the array. - - \returns an array of integers. -*/ -function GetAllContainedServiceBodyIDs( - $in_parent_id = 0 ///< This is the ID of the top Service body (will not be included in the reponse). -) { - $in_parent_id = intval($in_parent_id); - $ret = array( $in_parent_id ); - - $service_bodies = c_comdef_server::GetServer()->GetServiceBodyArray(); - - foreach ($service_bodies as $service_body) { - $sb_id = intval($service_body->GetID()); - $parent_id = intval($service_body->GetOwnerID()); - - if ($in_parent_id == $parent_id) { - $ret2 = GetAllContainedServiceBodyIDs($sb_id); - $ret = array_merge($ret, $ret2); - } - } - - return $ret; -} - -/*******************************************************************/ -/** \brief This displays the format keys, along with abbreviations to - display when the cursor is over them. - - \returns a string, containing the HTML rendered by the function, or, - if the $lite parameter is set to true, an associative, multidimensional - array, containing the information. -*/ -function BuildFormats( - $in_mtg_obj, ///< A reference to an instance of c_comdef_meeting. - $lite = false ///< If this is set to true, then the formats will be returned in an associative array, instead of as HTML. Default is false. -) { - $formats = ""; - - $formats_obj = $in_mtg_obj->GetMeetingDataValue('formats'); - - if (is_array($formats_obj) && count($formats_obj)) { - foreach ($formats_obj as $format) { - if ($format instanceof c_comdef_format) { - $key = htmlspecialchars($format->GetKey()); - $name = c_comdef_htmlspecialchars($format->GetLocalName()); - $desc = c_comdef_htmlspecialchars($format->GetLocalDescription()); - if ($lite) { - $formats[$key]['name'] = $name; - $formats[$key]['desc'] = $desc; - } else { - $formatspacer = ''; - if ($formats) { - $formatspacer = ' '; - } - - $formats .= "$formatspacer$key"; - } - } - } - } - - return $formats; -} - -/*******************************************************************/ -/** \brief Combines the town, borough and neighborhood into one string. - - \returns a string, containing the HTML rendered by the function. -*/ -function BuildTown( - $in_mtg_obj ///< A reference to an instance of c_comdef_meeting. -) { - $location_borough = c_comdef_htmlspecialchars(trim(stripslashes($in_mtg_obj->GetMeetingDataValue('location_city_subsection')))); - $location_town = c_comdef_htmlspecialchars(trim(stripslashes($in_mtg_obj->GetMeetingDataValue('location_municipality')))); - $location_neighborhood = c_comdef_htmlspecialchars(trim(stripslashes($in_mtg_obj->GetMeetingDataValue('location_neighborhood')))); - $location_province = c_comdef_htmlspecialchars(trim(stripslashes($in_mtg_obj->GetMeetingDataValue('location_province')))); - - if ($location_province) { - $location_town .= ', '.$location_province; - } - - if ($location_borough) { - $location_town = "$location_borough, $location_town"; - } - - if ($location_neighborhood) { - $location_town = "$location_town ($location_neighborhood)"; - } - - return $location_town; -} - -/*******************************************************************/ -/** \brief This creates a time string to be displayed for the meeting. - The display is done in non-military time, and "midnight" and - "noon" are substituted for 12:59:00, 00:00:00 and 12:00:00 - - \returns a string, containing the HTML rendered by the function. -*/ -function BuildTime( - $in_time, ///< A string. The value of the time field. - $in_integer = false ///< If true, the time is returned as an integer (Military time). -) { - $localized_strings = c_comdef_server::GetLocalStrings(); - - $time = null; - - if ($in_integer) { - $time = intval(str_replace(':', '', $in_time)) / 100; - } else { - if (($in_time == "00:00:00") || ($in_time == "23:59:00")) { - $time = c_comdef_htmlspecialchars($localized_strings['comdef_server_admin_strings']['meeting_editor_screen_meeting_noon_label']); - } elseif ($in_time == "12:00:00") { - $time = c_comdef_htmlspecialchars($localized_strings['comdef_server_admin_strings']['meeting_editor_screen_meeting_midnight_label']); - } else { - $time = c_comdef_htmlspecialchars(date($localized_strings['time_format'], strtotime($in_time))); - } - } - - return $time; -} - -/*******************************************************************/ -/** \brief This combines the location and street address fields. - - \returns a string, containing the HTML rendered by the function. -*/ -function BuildLocation( - $in_mtg_obj ///< A reference to an instance of c_comdef_meeting. -) { - $ret = ""; - - if ($in_mtg_obj instanceof c_comdef_meeting) { - $location_text = c_comdef_htmlspecialchars(trim(stripslashes($in_mtg_obj->GetMeetingDataValue('location_text')))); - $street = c_comdef_htmlspecialchars(trim(stripslashes($in_mtg_obj->GetMeetingDataValue('location_street')))); - $info = c_comdef_htmlspecialchars(trim(stripslashes($in_mtg_obj->GetMeetingDataValue('location_info')))); - - if ($location_text) { - $ret .= $location_text; - } - - if ($street) { - if ($ret) { - $ret .= ", "; - } - $ret .= $street; - } - - if ($info) { - if ($ret) { - $ret .= " "; - } - $ret .= "($info)"; - } - } - - return $ret; -} - -/*******************************************************************/ -/** \brief This function uses the server-level Google Maps API to - try to geocode an address from the string passed in. A instance - of c_comdef_server needs to have been instantiated by the time - this is called. - - \returns an associative array of two floating-point numbers, - representing the longitude and latitude, in degrees, of any - geocoded result. Null, if no valid result was returned. -*/ - -function GetGeocodeFromString( - $in_string, ///< The string to be checked. - $in_weekday_tinyint_array ///< An array of weekdays in which to filter for. -) { - $ret = null; - $localized_strings = c_comdef_server::GetLocalStrings(); - - $geo_uri = $localized_strings['comdef_server_admin_strings']['ServerMapsURL']; - - if ($localized_strings['region_bias']) { - $geo_uri .= '®ion='.$localized_strings['region_bias']; - } - - if ($localized_strings['google_api_key']) { - $geo_uri .= '&key='.$localized_strings['google_api_key']; - } - - // Bit of a kludge. If the string is just a number (a postcode), then we add the region bias directly to it. - if (is_numeric($in_string) && $localized_strings['region_bias']) { - $in_string .= " ".$localized_strings['region_bias']; - } - - $geo_uri = str_replace('##SEARCH_STRING##', urlencode($in_string), $geo_uri); - - // We set up a 200-mile bounds, in order to encourage Google to look in the proper place. - $m_p_deg = 100 / (111.321 * cos(deg2rad($localized_strings['search_spec_map_center']['latitude'])) * 1.609344); // Degrees for 100 miles. - $bounds_ar = strval($localized_strings['search_spec_map_center']['latitude'] - $m_p_deg).",". strval($localized_strings['search_spec_map_center']['longitude'] - $m_p_deg); // Southwest corner - $bounds_ar .= "|"; - $bounds_ar .= strval($localized_strings['search_spec_map_center']['latitude'] + $m_p_deg).",".strval($localized_strings['search_spec_map_center']['longitude'] + $m_p_deg); // Northeast corner - - $xml = simplexml_load_file($geo_uri); - - if ($xml->status == 'OK') { - $ret['longitude'] = floatval($xml->result->geometry->location->lng); - $ret['latitude'] = floatval($xml->result->geometry->location->lat); - $radius = c_comdef_server::HuntForRadius($localized_strings['number_of_meetings_for_auto'], $ret['longitude'], $ret['latitude'], $in_weekday_tinyint_array); - if ($radius) { - // The native units for the radius search is km. We need to convert to miles, if we are in miles. - if ($localized_strings['dist_units'] == 'mi') { - $radius /= 1.609344; - } - - $ret['radius'] = $radius; - } else { - $ret = null; - } - } - - return $ret; -} diff --git a/src/legacy/client_interface/csv/csv.php b/src/legacy/client_interface/csv/csv.php deleted file mode 100755 index 44202a3f3..000000000 --- a/src/legacy/client_interface/csv/csv.php +++ /dev/null @@ -1,1592 +0,0 @@ -/client_interface/csv/ - with the same parameters that you would send to an advanced search. The results - will be returned as a CSV file. - - This file can be called from other servers. - - This file is part of the Basic Meeting List Toolbox (BMLT). - - Find out more at: https://bmlt.app - - BMLT is free software: you can redistribute it and/or modify - it under the terms of the MIT License. - - BMLT is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - MIT License for more details. - - You should have received a copy of the MIT License along with this code. - If not, see . -*/ - -require_once(dirname(__FILE__).'/../../server/shared/classes/comdef_utilityclasses.inc.php'); -require_once(dirname(__FILE__).'/../../server/c_comdef_server.class.php'); -require_once(dirname(__FILE__).'/../../server/shared/Array2Json.php'); -require_once(dirname(__FILE__).'/../../server/shared/Array2XML.php'); - -/*******************************************************************/ -/** - \brief Queries the local server, and returns processed CSV data - - This requires that the "switcher=" parameter be set in the GET or - POST parameters: - - 'GetSearchResults' - This returns the search results. - - \returns CSV data, with the first row a key header. -*/ -function parse_redirect( - &$server ///< A reference to an instance of c_comdef_server -) { - $result = null; - $http_vars = array_merge_recursive($_GET, $_POST); - - $port = $_SERVER['SERVER_PORT'] ; - // IIS puts "off" in the HTTPS field, so we need to test for that. - $https = (!empty($_SERVER['HTTPS']) && (($_SERVER['HTTPS'] !== 'off') || ($port == 443))); - $server_path = $_SERVER['SERVER_NAME']; - $my_path = dirname(dirname(dirname($_SERVER['SCRIPT_NAME']))); - $server_path .= trim((($https && ($port != 443)) || (!$https && ($port != 80))) ? ':'.$port : '', '/'); - $http_vars['bmlt_root'] = 'http'.($https ? 's' : '').'://'.$server_path.$my_path; - - $langs = array ( $server->GetLocalLang() ); - $localized_strings = c_comdef_server::GetLocalStrings(); - - if (isset($http_vars['lang_enum'])) { - if (!is_array($http_vars['lang_enum'])) { - $langs = array ( trim($http_vars['lang_enum']) ); - } else { - $langs = $http_vars['lang_enum']; - } - } - - if (!isset($http_vars['switcher'])) { - $http_vars['switcher'] = ''; - } - - switch ($http_vars['switcher']) { - case 'GetSearchResults': - $meanLocationData = array(); - $formats_ar = array(); - - if (isset($http_vars['xml_data'])) { - $result2 = GetSearchResults($http_vars, $formats_ar, $meanLocationData); - $result = "\n"; - - $blueMeanieXML = ''; - $blueMeanieXML .= ''; - $blueMeanieXML .= ''.$meanLocationData['search_average']['location']['latitude'].''; - $blueMeanieXML .= ''.$meanLocationData['search_average']['location']['longitude'].''; - $blueMeanieXML .= ''; - $blueMeanieXML .= ''; - $blueMeanieXML .= ''.$meanLocationData['search_average']['radius']['miles'].''; - $blueMeanieXML .= ''.$meanLocationData['search_average']['radius']['kilometers'].''; - $blueMeanieXML .= ''; - $blueMeanieXML .= ''; - $blueMeanieXML .= ''; - $blueMeanieXML .= ''; - $blueMeanieXML .= ''.$meanLocationData['search_center']['location']['latitude'].''; - $blueMeanieXML .= ''.$meanLocationData['search_center']['location']['longitude'].''; - $blueMeanieXML .= ''; - $blueMeanieXML .= ''; - $blueMeanieXML .= ''.$meanLocationData['search_center']['radius']['miles'].''; - $blueMeanieXML .= ''.$meanLocationData['search_center']['radius']['kilometers'].''; - $blueMeanieXML .= ''; - $blueMeanieXML .= ''; - - if (!isset($http_vars['getMeanLocationData'])) { - $xsd_uri = 'http://'.htmlspecialchars(str_replace('/client_interface/xml', '/client_interface/xsd', trim(strtolower($_SERVER['SERVER_NAME'])).(($_SERVER['SERVER_PORT'] != 80) ? ':'.$_SERVER['SERVER_PORT'] : '').dirname($_SERVER['SCRIPT_NAME']).'/GetSearchResults.php')); - $result .= ""; - $result .= TranslateToXML($result2); - if ((isset($http_vars['get_used_formats']) || isset($http_vars['get_formats_only'])) && $formats_ar && is_array($formats_ar) && count($formats_ar)) { - if (isset($http_vars['get_formats_only'])) { - $result = ""; - $xsd_uri = 'http://'.htmlspecialchars(str_replace('/client_interface/xml', '/client_interface/xsd', trim(strtolower($_SERVER['SERVER_NAME'])).(($_SERVER['SERVER_PORT'] != 80) ? ':'.$_SERVER['SERVER_PORT'] : '').dirname($_SERVER['SCRIPT_NAME']).'/GetFormats.php')); - $result .= ""; - } else { - $result .= ""; - } - $result3 = GetFormats($server, $langs, null, $formats_ar); - $result .= TranslateToXML($result3); - $result .= ""; - } - - if (!isset($http_vars['get_formats_only'])) { - $result .= ""; - $result .= $blueMeanieXML; - $result .= ""; - $result .= ""; - } - } else { - $xsd_uri = 'http://'.htmlspecialchars(str_replace('/client_interface/xml', '/client_interface/xsd', trim(strtolower($_SERVER['SERVER_NAME'])).(($_SERVER['SERVER_PORT'] != 80) ? ':'.$_SERVER['SERVER_PORT'] : '').dirname($_SERVER['SCRIPT_NAME']).'/GetMeetingLocationInfo.php')); - $result .= ""; - $result .= $blueMeanieXML; - $result .= ""; - } - } elseif (isset($http_vars['gpx_data'])) { - $result2 = GetSearchResults($http_vars, $formats_ar); - $result2 = returnArrayFromCSV(explode("\n", $result2)); - if (is_array($result2) && count($result2)) { - $result = ""; - $result .= ""; - - $minlng = 361; - $minlat = 361; - $maxlng = -361; - $maxlat = -361; - - foreach ($result2 as $meeting) { - $lng = floatval($meeting['longitude']); - $lat = floatval($meeting['latitude']); - - if ($lng || $lat) { - $minlng = min($minlng, $lng); - $minlat = min($minlat, $lat); - $maxlng = max($maxlng, $lng); - $maxlat = max($maxlat, $lat); - } - } - - $result .= ''; - - foreach ($result2 as $meeting) { - $desc = prepareSimpleLine($meeting); - - $name = c_comdef_htmlspecialchars(trim(stripslashes($meeting['meeting_name']))); - if (!$name) { - $name = "NA Meeting"; - } - - $lng = floatval($meeting['longitude']); - $lat = floatval($meeting['latitude']); - $type = 'NA Meeting'; - - if ($lng || $lat) { - $result .= ''; - $result .= ''; - if ($desc) { - $result .= ''; - } - - $result .= ''; - $result .= 'Diamond, Blue'; - $result .= ''; - } - } - - $result .= ''; - } - } elseif (isset($http_vars['kml_data'])) { - $result2 = GetSearchResults($http_vars, $formats_ar); - $result2 = returnArrayFromCSV(explode("\n", $result2)); - if (is_array($result2) && count($result2)) { - $result = ""; - $result .= ''; - $result .= ''; - - foreach ($result2 as $meeting) { - $desc = prepareSimpleLine($meeting); - $address = prepareSimpleLine($meeting, false); - - $name = c_comdef_htmlspecialchars(trim(stripslashes($meeting['meeting_name']))); - - if (!$name) { - $name = "NA Meeting"; - } - - $lng = floatval($meeting['longitude']); - $lat = floatval($meeting['latitude']); - - if ($lng || $lat) { - $result .= ''; - $result .= ''.htmlspecialchars($name).''; - - if ($address) { - $result .= '
'.$address.'
'; - } - - if ($desc) { - $result .= ''.$desc.''; - } - - $result .= ''; - $result .= ''; - $result .= htmlspecialchars($lng).','.htmlspecialchars($lat).',0'; - $result .= ''; - $result .= ''; - $result .= '
'; - } - } - - $result .= '
'; - $result .= '
'; - } - } elseif (isset($http_vars['poi_data'])) { - $result2 = GetSearchResults($http_vars, $formats_ar); - $result2 = returnArrayFromCSV(explode("\n", $result2)); - if (is_array($result2) && count($result2)) { - $result = "lon,lat,name,desc\n"; - foreach ($result2 as $meeting) { - $desc = htmlspecialchars_decode(prepareSimpleLine($meeting)); - - $name = trim(stripslashes($meeting['meeting_name'])); - - if (!$name) { - $name = "NA Meeting"; - } - - $name = addcslashes($name, '"'); - $desc = addcslashes($desc, '"'); - - $lng = floatval($meeting['longitude']); - $lat = floatval($meeting['latitude']); - - if ($lng || $lat) { - $result .= '"'.$lng.'","'.$lat.'","'.$name.'","'.$desc.'"'."\n"; - } - } - } - } elseif (isset($http_vars['json_data'])) { - $result = TranslateToJSON(GetSearchResults($http_vars, $formats_ar, $meanLocationData)); - if ((isset($http_vars['get_used_formats']) || isset($http_vars['get_formats_only']))) { - if (isset($http_vars['get_formats_only'])) { - $format_list = '[]'; - if (isset($formats_ar) && is_array($formats_ar) && count($formats_ar)) { - $format_list = TranslateToJSON(GetFormats($server, $langs, null, $formats_ar)); - } - - $result = '{"formats":'.$format_list.'}'; - } else { - if (isset($http_vars['appendMeanLocationData'])) { - $result = '{"meetings":'.$result.',"formats":'.TranslateToJSON(GetFormats($server, $langs, null, $formats_ar)).',"locationInfo":'.array2json($meanLocationData).'}'; - } else { - $format_list = '[]'; - if (isset($formats_ar) && is_array($formats_ar) && count($formats_ar)) { - $format_list = TranslateToJSON(GetFormats($server, $langs, null, $formats_ar)); - } - - $result = '{"meetings":'.$result.',"formats":'.$format_list.'}'; - } - } - } else { - if (isset($http_vars['getMeanLocationData']) && is_array($meanLocationData) && count($meanLocationData)) { - if (isset($http_vars['appendMeanLocationData'])) { - $result = '{"meetings":'.$result.',"locationInfo":'.array2json($meanLocationData).'}'; - } else { - $result = array2json(array ( 'locationInfo' => $meanLocationData )); - } - } - } - } else { - $result2 = GetSearchResults($http_vars, $formats_ar); - - if (isset($http_vars['get_formats_only'])) { - $result2 = GetFormats($server, $langs, null, $formats_ar); - - if (!$result2) { - $result2 = '[]'; - } - } - - $result = $result2; - } - break; - - case 'GetFormats': - $show_all_formats = isset($http_vars['show_all']) && $http_vars['show_all'] == '1'; - $formatKeyStrings = null; - if (isset($http_vars['key_strings']) && is_array($http_vars['key_strings']) && count($http_vars['key_strings'])) { - $formatKeyStrings = $http_vars['key_strings']; - } else if (isset($http_vars['key_strings'])) { - $formatKeyStrings = [$http_vars['key_strings']]; - } - - $result2 = GetFormats($server, $langs, $formatKeyStrings, null, $show_all_formats); - - if (isset($http_vars['xml_data'])) { - $result = ""; - $xsd_uri = 'http://'.htmlspecialchars(str_replace('/client_interface/xml', '/client_interface/xsd', $_SERVER['SERVER_NAME'].(($_SERVER['SERVER_PORT'] != 80) ? ':'.$_SERVER['SERVER_PORT'] : '').dirname($_SERVER['SCRIPT_NAME']).'/GetFormats.php')); - $result .= ""; - $result .= TranslateToXML($result2); - $result .= ""; - } elseif (isset($http_vars['json_data'])) { - $result = TranslateToJSON($result2); - if (!$result) { - $result = '[]'; - } - } else { - $result = $result2; - } - break; - - case 'GetServiceBodies': - $recursive = isset($http_vars['recursive']) && $http_vars['recursive'] == '1'; - $parents = isset($http_vars['parents']) && $http_vars['parents'] == '1'; - - $services = null; - if (isset($http_vars['services'])) { - $services = is_array($http_vars['services']) ? $http_vars['services'] : array($http_vars['services']); - } - $result2 = GetServiceBodies($server, $services, $recursive, $parents); - - if (isset($http_vars['xml_data'])) { - $result = ""; - $xsd_uri = 'http://'.htmlspecialchars(str_replace('/client_interface/xml', '/client_interface/xsd', $_SERVER['SERVER_NAME'].(($_SERVER['SERVER_PORT'] != 80) ? ':'.$_SERVER['SERVER_PORT'] : '').dirname($_SERVER['SCRIPT_NAME']).'/GetServiceBodies.php')); - $result .= ""; - $result .= TranslateToXML($result2); - $result .= ""; - } elseif (isset($http_vars['json_data'])) { - $result = TranslateToJSON($result2); - if (!$result) { - $result = '[]'; - } - } else { - $result = $result2; - } - break; - - case 'GetChanges': - $start_date = null; - $end_date = null; - $meeting_id = null; - $service_body_id = null; - $meetings_only = true; - - if (isset($http_vars['start_date'])) { - $start_date = strtotime(trim($http_vars['start_date'])); - } - - if (isset($http_vars['end_date'])) { - $end_date = strtotime(trim($http_vars['end_date'])); - } - - if (isset($http_vars['meeting_id'])) { - $meeting_id = intval($http_vars['meeting_id']); - } - - if (isset($http_vars['service_body_id'])) { - $service_body_id = intval($http_vars['service_body_id']); - } - - $result2 = GetChanges($http_vars, $start_date, $end_date, $meeting_id, $service_body_id); - - if (isset($http_vars['xml_data'])) { - $xsd_uri = 'http://'.htmlspecialchars(str_replace('/client_interface/xml', '/client_interface/xsd', $_SERVER['SERVER_NAME'].(($_SERVER['SERVER_PORT'] != 80) ? ':'.$_SERVER['SERVER_PORT'] : '').dirname($_SERVER['SCRIPT_NAME']).'/GetChanges.php')); - $result = "".TranslateToXML($result2).""; - } elseif (isset($http_vars['json_data'])) { - $result = TranslateToJSON($result2); - if (!$result) { - $result = '[]'; - } - } else { - $result = $result2; - } - break; - - case 'GetServerInfo': - $result2 = GetServerInfo(); - if (isset($http_vars['xml_data'])) { - $result = ""; - $xsd_uri = 'http://'.htmlspecialchars(str_replace('/client_interface/xml', '/client_interface/xsd', $_SERVER['SERVER_NAME'].(($_SERVER['SERVER_PORT'] != 80) ? ':'.$_SERVER['SERVER_PORT'] : '').dirname($_SERVER['SCRIPT_NAME']).'/ServerInfo.php')); - $result .= ""; - $result .= TranslateToXML($result2); - $result .= ""; - } elseif (isset($http_vars['json_data'])) { - $result = TranslateToJSON($result2); - } else { - $result = $result2; - } - break; - - case 'GetNAWSDump': - $result = CSVHandleNawsDump($http_vars, $server); - break; - - case 'GetCoverageArea': - $result2 = GetCoverageArea(); - if (isset($http_vars['xml_data'])) { - $result = ""; - $xsd_uri = 'http://'.htmlspecialchars(str_replace('/client_interface/xml', '/client_interface/xsd', $_SERVER['SERVER_NAME'].(($_SERVER['SERVER_PORT'] != 80) ? ':'.$_SERVER['SERVER_PORT'] : '').dirname($_SERVER['SCRIPT_NAME']).'/GetCoverageArea.php')); - $result .= ""; - $result .= TranslateToXML($result2); - $result .= ""; - } elseif (isset($http_vars['json_data'])) { - $result = TranslateToJSON($result2); - } else { - $result = $result2; - } - break; - - case 'GetFieldKeys': - $keys = c_comdef_meeting::GetFullTemplate(); - - if (isset($keys) && is_array($keys) && count($keys)) { - $result2 = array ('"key","description"'); - - foreach ($keys as $key) { - if (($key['visibility'] != 1) && ($key['key'] != 'published') && ($key['key'] != 'shared_group_id_bigint')) { - $result2[] = '"'.$key['key'].'","'.$key['field_prompt'].'"'; - } - } - - $result2 = implode("\n", $result2); - - if (isset($http_vars['xml_data'])) { - $result = ""; - $xsd_uri = 'http://'.htmlspecialchars(str_replace('/client_interface/xml', '/client_interface/xsd', $_SERVER['SERVER_NAME'].(($_SERVER['SERVER_PORT'] != 80) ? ':'.$_SERVER['SERVER_PORT'] : '').dirname($_SERVER['SCRIPT_NAME']).'/GetFieldKeys.php')); - $result .= ""; - $result .= TranslateToXML($result2); - $result .= ""; - } elseif (isset($http_vars['json_data'])) { - $result = TranslateToJSON($result2); - } else { - $result = $result2; - } - } - break; - - case 'GetFieldValues': - $meeting_key = trim($http_vars['meeting_key']); - $values = c_comdef_meeting::GetAllValuesForKey($meeting_key); - if (isset($values) && is_array($values) && count($values)) { - $result2 = array ('"'.$meeting_key.'","ids"'); - - foreach ($values as $value => $ids) { - if (($meeting_key == 'formats') && isset($http_vars['specific_formats']) && trim($http_vars['specific_formats'])) { - $targeted_formats = explode(',', trim($http_vars['specific_formats'])); - if (is_array($targeted_formats) && count($targeted_formats)) { - $targeted_formats = array_map(intval, $targeted_formats); - $these_formats = explode("\t", $value); - - if (is_array($these_formats) && count($these_formats)) { - $these_formats = array_map(intval, $these_formats); - $value = array_intersect($these_formats, $targeted_formats); - if (isset($http_vars['all_formats'])) { - $diff = array_diff($targeted_formats, $value); - if (isset($diff) && is_array($diff) && count($diff)) { - continue; - } - } - - if (!count($value)) { - continue; - } else { - $value = implode("\t", $value); - } - } else { - continue; - } - } else { - break; - } - } elseif ($meeting_key == 'worldid_mixed') { - if ($value != 'NULL') { - $value = trim($value); - } - } - - $ids = explode('\t', $ids); - $ids = trim(implode("\t", $ids)); - $result2[] = '"'.$value.'","'.$ids.'"'; - } - - $result3 = array(); - - foreach ($result2 as $resultRow) { - list ( $key, $value ) = explode(',', $resultRow); - - $value = explode("\t", trim($value, '"')); - $oldValue = explode("\t", array_key_exists($key, $result3) ? $result3[$key] : ""); - $value = array_unique(array_merge($value, $oldValue)); - asort($value); - $value = trim(implode("\t", $value)); - $result3[$key] = $value; - } - - $result2 = array(); - foreach ($result3 as $key => $value) { - $key = str_replace('&APOS&', ',', trim($key, '"')); - - $result2[] = "\"$key\",\"$value\""; - } - - $result2 = implode("\n", $result2); - } - - if (isset($http_vars['xml_data'])) { - $result = ""; - $xsd_uri = 'http://'.htmlspecialchars(str_replace('/client_interface/xml', '/client_interface/xsd', $_SERVER['SERVER_NAME'].(($_SERVER['SERVER_PORT'] != 80) ? ':'.$_SERVER['SERVER_PORT'] : '').dirname($_SERVER['SCRIPT_NAME']).'/GetFieldValues.php')); - $result .= ""; - $result .= str_replace("\t", ',', TranslateToXML($result2)); - $result .= ""; - } elseif (isset($http_vars['json_data'])) { - $result = TranslateToJSON($result2); - } else { - $result = str_replace("\t", ',', $result2); - } - break; - - default: - $result = HandleDefault($http_vars); - break; - } - - return $result; -} - -/*******************************************************************/ -/** - \brief This returns a string, with the meeting's daya, time and location data in a simple string. - - \returns a string, containing the meeting day, time and location summary. -*/ -function prepareSimpleLine( - $meeting, /**< An associative array of meeting data */ - $withDate = true /**< If false (default is true), the weekday and time will not be added. */ -) { - $localized_strings = c_comdef_server::GetLocalStrings(); - - $location_borough = array_key_exists('location_city_subsection', $meeting) ? c_comdef_htmlspecialchars(trim(stripslashes($meeting['location_city_subsection']))) : ""; - $location_neighborhood = array_key_exists('location_neighborhood', $meeting) ? c_comdef_htmlspecialchars(trim(stripslashes($meeting['location_neighborhood']))) : ""; - $location_province = array_key_exists('location_province', $meeting) ? c_comdef_htmlspecialchars(trim(stripslashes($meeting['location_province']))) : ""; - $location_nation = array_key_exists('location_nation', $meeting) ? c_comdef_htmlspecialchars(trim(stripslashes($meeting['location_nation']))) : ""; - $location_postal_code_1 = array_key_exists('location_postal_code_1', $meeting) ? c_comdef_htmlspecialchars(trim(stripslashes($meeting['location_postal_code_1']))) : ""; - $location_text = array_key_exists('location_text', $meeting) ? c_comdef_htmlspecialchars(trim(stripslashes($meeting['location_text']))) : ""; - $street = array_key_exists('location_street', $meeting) ? c_comdef_htmlspecialchars(trim(stripslashes($meeting['location_street']))) : ""; - $info = array_key_exists('location_info', $meeting) ? c_comdef_htmlspecialchars(trim(stripslashes($meeting['location_info']))) : ""; - $town = array_key_exists('location_municipality', $meeting) ? c_comdef_htmlspecialchars(trim(stripslashes($meeting['location_municipality']))) : ""; - $desc = $withDate ? '' : $location_text; - - if ($location_borough) { - $town = $location_borough; - } - - if ($location_province) { - $town = "$town, $location_province"; - } - - if ($location_postal_code_1) { - $town = "$town, $location_postal_code_1"; - } - - if ($location_nation) { - $town = "$town, $location_nation"; - } - - if ($withDate && $location_neighborhood) { - $town = "$town ($location_neighborhood)"; - } - - if ($street) { - if ($desc) { - $desc .= ", "; - } - $desc .= $street; - } - - if ($town) { - if ($desc) { - $desc .= ", "; - } - $desc .= $town; - } - - if ($withDate && $info) { - if ($desc) { - $desc .= " ($info)"; - } else { - $desc = $info; - } - } - - $weekday = intval(trim(stripslashes($meeting['weekday_tinyint']))); - $time = date($localized_strings['time_format'], strtotime($meeting['start_time'])); - $weekday = $localized_strings['comdef_server_admin_strings']['meeting_search_weekdays_names'][$weekday]; - - $ret = null; - - if ($withDate && $weekday) { - $ret = $weekday; - } - - if ($withDate && $time) { - if ($ret) { - $ret .= ', '; - } - - $ret .= $time; - } - - if ($ret) { - $ret .= ', '; - } - - $ret .= $desc; - - return $ret; -} - -/*******************************************************************/ -/** - \brief -*/ -function CSVHandleNawsDump( - $in_http_Vars, ///< The ID of the Service Body to dump - $in_server ///< The Root Server instance -) { - $sb = $in_server->GetServiceBodyByIDObj(intval($in_http_Vars['sb_id'])); - - if ($sb) { - require_once(dirname(__FILE__).'/search_results_csv.php'); - $service_bodies = array ( 'services' => c_comdef_server::GetServiceBodyHierarchyIDs(intval($in_http_Vars['sb_id'])) ); - - $cc = preg_replace('|[\W]|', '_', strtoupper(trim($sb->GetWorldID()))); - - if (preg_match('|^_+$|', $cc)) { - $cc = ''; - } - - $filename = preg_replace('|[\W]|', '_', strtolower(trim($sb->GetLocalName()))); - - if (preg_match('|^_+$|', $filename)) { - $filename = ''; - } - - $filename .= date('_Y_m_d_H_i_s'); - - if ($cc) { - $filename = "$cc"."_$filename"; - } - - $sb_array = array("services" => array(), "advanced_published" => 0); - - // Make sure we all have NAWS IDs. - foreach ($service_bodies["services"] as $sbID) { - $service_body_object = $in_server->GetServiceBodyByIDObj($sbID); - if ($service_body_object && $service_body_object->GetWorldID()) { - $sb_array["services"][] = $sbID; - } - } - header("Content-Disposition: attachment; filename=BMLT_$filename.csv"); - return ReturnNAWSFormatCSV($sb_array, $in_server); - } -} - -/*******************************************************************/ -/** - \brief This returns an associative array from the given CSV, which is an array of lines, and the top line is the field names. - - \returns an associative array. Each main element will be one line, and each line will be an associative array of fields. If a field is not present in the line, it is not included. -*/ -function returnArrayFromCSV( - $inCSVArray ///< A array of CSV data, split as lines (each element is a single text line of CSV data). the first line is the header (array keys). -) { - $ret = null; - - $desc_line = $inCSVArray[0]; // Get the field names. - $desc_line = explode('","', trim($desc_line, '"')); - - for ($index = 1; $index < count($inCSVArray); $index++) { - $interim_line = explode('","', trim($inCSVArray[$index], '"')); - - if ($interim_line && count($interim_line)) { - $result = null; - - $interim_line = array_combine($desc_line, $interim_line); - - foreach ($interim_line as $key => $value) { - $value = trim($value); - - if ($value) { - $result[$key] = $value; - } - } - - if (is_array($result) && count($result)) { - $ret[] = $result; - } - } - } - - return $ret; -} - -/*******************************************************************/ -/** - \brief Calculates the distance, in Km, between two long/lat pairs. - This uses the Haversine formula. - Cribbed from here: http://blog.voltampmedia.com/2011/12/17/php-implementation-of-haversine-computation/ - - \returns A floating-point, positive number. The distance, in miles. -*/ -function calcDistanceInMiles( - $lat_1, ///< The latitude of the first point, in degrees. - $long_1, ///< The longitude of the first point, in degrees. - $lat_2, ///< The latitude of the second point, in degrees. - $long_2 ///< The longitude of the second point, in degrees. -) { - $sin_lat = sin(deg2rad($lat_2 - $lat_1) / 2.0); - $sin2_lat = $sin_lat * $sin_lat; - - $sin_long = sin(deg2rad($long_2 - $long_1) / 2.0); - $sin2_long = $sin_long * $sin_long; - - $cos_lat_1 = cos($lat_1); - $cos_lat_2 = cos($lat_2); - - $sqrt = sqrt($sin2_lat + ($cos_lat_1 * $cos_lat_2 * $sin2_long)); - - $earth_radius = 3963.1676; // in miles - - $distance = 2.0 * $earth_radius * asin($sqrt); - - return $distance; -} - -/*******************************************************************/ -/** - \brief This returns the search results, in whatever form was requested. - - \returns CSV data, with the first row a key header. -*/ -function GetSearchResults( - $in_http_vars, ///< The HTTP GET and POST parameters. - &$formats_ar = null, ///< This will return the formats used in this search. - &$meanLocationData = null ///< This is a passed in receptacle for some location data calculations. -) { - if (!( isset($in_http_vars['geo_width']) && $in_http_vars['geo_width'] ) && isset($in_http_vars['bmlt_search_type']) && ($in_http_vars['bmlt_search_type'] == 'advanced') && isset($in_http_vars['advanced_radius']) && isset($in_http_vars['advanced_mapmode']) && $in_http_vars['advanced_mapmode'] && ( floatval($in_http_vars['advanced_radius'] != 0.0) ) && isset($in_http_vars['lat_val']) && isset($in_http_vars['long_val']) && ( (floatval($in_http_vars['lat_val']) != 0.0) || (floatval($in_http_vars['long_val']) != 0.0) )) { - $in_http_vars['geo_width'] = $in_http_vars['advanced_radius']; - } elseif (!( isset($in_http_vars['geo_width']) && $in_http_vars['geo_width'] ) && isset($in_http_vars['bmlt_search_type']) && ($in_http_vars['bmlt_search_type'] == 'advanced')) { - $in_http_vars['lat_val'] = null; - $in_http_vars['long_val'] = null; - } elseif (!isset($in_http_vars['geo_loc']) || $in_http_vars['geo_loc'] != 'yes') { - if (!isset($in_http_vars['geo_width'])) { - $in_http_vars['geo_width'] = 0; - } - } - - require_once(dirname(__FILE__).'/search_results_csv.php'); - $geocode_results = null; - $ignore_me = null; - $meeting_objects = array(); - $result = DisplaySearchResultsCSV($in_http_vars, $ignore_me, $geocode_results, $meeting_objects); - $locationData = array ( ); - - if (is_array($meeting_objects) && count($meeting_objects)) { - foreach ($meeting_objects as $one_meeting) { - if (isset($in_http_vars['getMeanLocationData']) || (isset($meanLocationData)&& is_array($meanLocationData))) { - $locationData[] = array ( 'long' => floatval($one_meeting->GetMeetingDataValue('longitude')), 'lat' => floatval($one_meeting->GetMeetingDataValue('latitude')) ); - } - - if (is_array($formats_ar)) { - $formats = $one_meeting->GetMeetingDataValue('formats'); - - foreach ($formats as $format) { - if ($format && ($format instanceof c_comdef_format)) { - $format_shared_id = $format->GetSharedID(); - $formats_ar[$format_shared_id] = $format; - } - } - } - } - } - - if (count($locationData)) { // If the caller just wants an average location report, then give them that. - $avgLong = 0.0; - $avgLat = 0.0; - $minLong = 1000.0; - $maxLong = -1000.0; - $minLat = 1000.0; - $maxLat = -1000.0; - - foreach ($locationData as $location) { - $avgLong += $location['long']; - $avgLat += $location['lat']; - $minLong = min($minLong, $location['long']); - $maxLong = max($maxLong, $location['long']); - $minLat = min($minLat, $location['lat']); - $maxLat = max($maxLat, $location['lat']); - } - - $avgLong = $avgLong / floatVal(count($locationData)); - $avgLat = $avgLat / floatVal(count($locationData)); - $centerLat = ($maxLat + $minLat) / 2.0; - $centerLong = ($maxLong + $minLong) / 2.0; - - $d1 = calcDistanceInMiles($avgLat, $avgLong, $maxLat, $maxLong); - $d2 = calcDistanceInMiles($avgLat, $avgLong, $minLat, $minLong); - $d3 = calcDistanceInMiles($avgLat, $avgLong, $minLat, $maxLong); - $d4 = calcDistanceInMiles($avgLat, $avgLong, $maxLat, $minLong); - - $avg_radiusMi = max($d1, $d2, $d3, $d4); - $avg_radiusKm = $avg_radiusMi * 1.60934; - - $hard_radiusMi = calcDistanceInMiles($centerLat, $centerLong, $maxLat, $maxLong); - $hard_radiusKm = $hard_radiusMi * 1.60934; - - if (isset($meanLocationData) && is_array($meanLocationData)) { - $meanLocationData = array ( 'search_average' => array ( 'location' => array ( 'latitude' => $avgLat, 'longitude' => $avgLong, ), 'radius' => array ( 'miles' => $avg_radiusMi, 'kilometers' => $avg_radiusKm ) ), - 'search_center' => array ( 'location' => array ( 'latitude' => $centerLat, 'longitude' => $centerLong, ), 'radius' => array ( 'miles' => $hard_radiusMi, 'kilometers' => $hard_radiusKm ) )); - } - - if (isset($in_http_vars['getMeanLocationData'])) { - $result = '"average_center_latitude","average_center_longitude","average_radius_mi","average_radius_km","search_center_latitude","search_center_longitude","search_center_radius_mi","search_center_radius_km"'."\n"; - $result .= '"'.$avgLat.'","'.$avgLong.'","'.$avg_radiusMi.'","'.$avg_radiusKm.'","'.$centerLat.'","'.$centerLong.'","'.$hard_radiusMi.'","'.$hard_radiusKm.'"'; - } - } - - if (!isset($in_http_vars['getMeanLocationData']) && isset($in_http_vars['data_field_key']) && $in_http_vars['data_field_key']) { - // At this point, we have everything in a CSV. We separate out just the field we want. - $temp_keyed_array = array(); - $result = explode("\n", $result); - $keys = array_shift($result); - $keys = explode("\",\"", trim($keys, '"')); - $the_keys = explode(',', $in_http_vars['data_field_key']); - - $result2 = array(); - foreach ($result as $row) { - if ($row) { - $index = 0; - $row = explode('","', trim($row, '",')); - $row_columns = array(); - foreach ($row as $column) { - if (!$column) { - $column = ' '; - } - if (in_array($keys[$index++], $the_keys)) { - array_push($row_columns, $column); - } - } - $result2[$row[0]] = '"'.implode('","', $row_columns).'"'; - } - } - - $the_keys = array_intersect($keys, $the_keys); - $result = '"'.implode('","', $the_keys)."\"\n".implode("\n", $result2); - } - return $result; -} - -/*******************************************************************/ -/** \brief Returns a set of two coordinates that define a rectangle - that encloses all of the meetings. - - \returns a dictionary, with the two coordinates. -*/ -function GetCoverageArea() -{ - $result = c_comdef_server::GetCoverageArea(); - $ret = null; - - if (isset($result) && is_array($result) && count($result)) { - $ret = array ( '"nw_corner_longitude","nw_corner_latitude","se_corner_longitude","se_corner_latitude"' ); - $ret[1] = '"'.strval($result["nw_corner"]["longitude"]).'","'.strval($result["nw_corner"]["latitude"]).'","'.strval($result["se_corner"]["longitude"]).'","'.strval($result["se_corner"]["latitude"]).'"'; - $ret = implode("\n", $ret); - } - - return $ret; -} - -/*******************************************************************/ -/** - \brief This returns the complete formats table. - - \returns CSV data, with the first row a key header. -*/ -function GetFormats( - &$server, ///< A reference to an instance of c_comdef_server - $in_lang = null, ///< The language of the formats to be returned. - $in_key_strings = null, ///< If supplied, an array of format key strings to be returned. - $in_formats = null, //< If supplied, an already-fetched array of formats. - $show_all = false //< If true return all formats regardless of if they are used or not. -) { - $my_keys = array ( 'key_string', - 'name_string', - 'description_string', - 'lang', - 'id', - 'world_id', - 'root_server_uri', - 'format_type_enum', - ); - - $ret = null; - - $formats_obj = $server->GetFormatsObj(); - if ($formats_obj instanceof c_comdef_formats) { - $langs = $server->GetFormatLangs(); - $used_formats = $server->GetUsedFormatIDs(); - if (isset($in_lang) && is_array($in_lang) && count($in_lang)) { - $langs2 = array(); - foreach ($in_lang as $key) { - if (array_key_exists($key, $langs)) { - $langs2[$key] = $langs[$key]; - } - } - - $langs = $langs2; - } elseif (array_key_exists($in_lang, $langs)) { - $langs = array ( $in_lang => $langs[$in_lang] ); - } - - $ret .= '"'.implode('","', $my_keys)."\"\n"; - foreach ($langs as $key => $value) { - if ($in_formats) { - $format_array = $in_formats; - } else { - $format_array = $formats_obj->GetFormatsByLanguage($key); - } - - if (is_array($format_array) && count($format_array)) { - foreach ($format_array as $format) { - if ($format instanceof c_comdef_format) { - $localized_format = $server->GetOneFormat($format->GetSharedID(), $key); - - if (isset($in_key_strings) && is_array($in_key_strings) && count($in_key_strings)) { - if (!in_array($localized_format->GetKey(), $in_key_strings)) { - continue; - } - } - - if ($localized_format instanceof c_comdef_format) { - $line = ''; - foreach ($my_keys as $ky) { - if ($line) { - $line .= ','; - } - - $val = ''; - - switch ($ky) { - case 'lang': - $val = $key; - break; - - case 'id': - $val = $localized_format->GetSharedID(); - break; - - case 'key_string': - $val = $localized_format->GetKey(); - break; - - case 'name_string': - $val = $localized_format->GetLocalName(); - break; - - case 'description_string': - $val = $localized_format->GetLocalDescription(); - break; - - case 'world_id': - $val = $localized_format->GetWorldID(); - break; - - case 'root_server_uri': - $val = dirname(dirname(GetURLToMainServerDirectory(true))); - break; - - case 'format_type_enum': - $val = $localized_format->GetFormatType(); - break; - } - - $line .= '"'.str_replace('"', '\"', trim($val)).'"'; - } - if ($show_all || in_array($localized_format->GetSharedID(), $used_formats)) { - $ret .= "$line\n"; - } - } - } - } - } - } - } - - return $ret; -} - -/*******************************************************************/ -/** - \brief This returns the complete Service bodies table. - - \returns CSV data, with the first row a key header. -*/ -function GetServiceBodies( - &$server, ///< A reference to an instance of c_comdef_server - $services = null, - $recursive = false, - $parents = false -) { - $ret = array (); - $localized_strings = c_comdef_server::GetLocalStrings(); - - $ret[0] = '"id","parent_id","name","description","type","url","helpline","world_id"'; - - if ($localized_strings['include_service_body_email_in_semantic']) { - $ret[0] .= ',"contact_email"'; - } - - $servicesInclude = array(); - $servicesExclude = array(); - if ($services) { - foreach ($services as $id) { - if (substr($id, 0, 1) == "-") { - array_push($servicesExclude, substr($id, 1)); - } else { - array_push($servicesInclude, $id); - } - } - } - - if ($recursive) { - $servicesInclude = array_merge($servicesInclude, GetChildServiceBodies($server, $servicesInclude)); - $servicesExclude = array_merge($servicesExclude, GetChildServiceBodies($server, $servicesExclude)); - } - - if ($parents) { - $servicesInclude = array_merge($servicesInclude, GetParentServiceBodies($server, $servicesInclude)); - } - - try { - $array_obj = $server->GetServiceBodyArray(); - if (is_array($array_obj) && count($array_obj)) { - foreach ($array_obj as &$sb) { - if ($sb instanceof c_comdef_service_body) { - if (count($servicesInclude) && !in_array($sb->GetID(), $servicesInclude)) { - continue; - } - if (count($servicesExclude) && in_array($sb->GetID(), $servicesExclude)) { - continue; - } - $row = array(); - $row[] = $sb->GetID(); - $row[] = $sb->GetOwnerID(); - $row[] = $sb->GetLocalName(); - $description = preg_replace('|[^\S]+?|', " ", $sb->GetLocalDescription()); - $row[] = $description; - $row[] = $sb->GetSBType(); - $row[] = $sb->GetURI(); - $row[] = trim($sb->GetHelpline()); - $row[] = $sb->GetWorldID(); - if ($localized_strings['include_service_body_email_in_semantic']) { - $row[] = trim($sb->GetContactEmail()); - } - $row = '"'.implode('","', $row).'"'; - $ret[] = $row; - } - } - } - } catch (Exception $e) { - } - - return implode("\n", $ret); -} - -function GetParentServiceBodies($server, $serviceBodyIds) -{ - $ret = array(); - $serviceBodyArray = $server->GetServiceBodyArray(); - $parents = $serviceBodyIds; - while (count($parents)) { - $newParents = array(); - foreach ($serviceBodyArray as $serviceBody) { - if (in_array($serviceBody->GetID(), $parents) && !in_array($serviceBody->GetOwnerID(), $ret)) { - array_push($newParents, $serviceBody->GetOwnerID()); - array_push($ret, $serviceBody->GetOwnerID()); - } - } - $parents = $newParents; - } - return $ret; -} - -function GetChildServiceBodies($server, $parents) -{ - $ret = array(); - $children = $parents; - $serviceBodyArray = $server->GetServiceBodyArray(); - while (count($children)) { - $newChildren = array(); - foreach ($serviceBodyArray as $serviceBody) { - if (in_array($serviceBody->GetOwnerID(), $children) && !in_array($serviceBody->GetID(), $ret)) { - array_push($newChildren, $serviceBody->GetID()); - array_push($ret, $serviceBody->GetID()); - } - } - $children = $newChildren; - } - return $ret; -} - -/*******************************************************************/ -/** - \brief This returns a line of server info. - - \returns CSV data, with the first row a key header. -*/ -function GetServerInfo() -{ - require(dirname(__FILE__).'/../../server/config/get-config.php'); - $ret = ''; - $version_array = GetServerVersion(); - $version_num = (intval($version_array[0]) * 1000000) + (intval($version_array[1]) * 1000) + intval($version_array[2]); - $version_string = strval($version_array[0]).'.'.strval($version_array[1]).'.'.strval($version_array[2]); - $lang_array = c_comdef_server::GetServerLangs(); - $lang_string = implode(',', array_keys($lang_array)); - $localStrings = c_comdef_server::GetLocalStrings(); - $default_lang = strval($localStrings['enum']); - $canAdmin = isset($g_enable_semantic_admin) && $g_enable_semantic_admin ? '1' : '0'; - $centerLongLatZoom = implode(',', $localStrings['search_spec_map_center']); - $canEmail = isset($g_enable_email_contact) && $g_enable_email_contact ? '1' : '0'; - $includeServiceBodiesOnEmails = isset($include_service_body_admin_on_emails) && $include_service_body_admin_on_emails ? '1' : '0'; - $changeDepth = strVal(intval($change_depth_for_meetings)); - $dbVersion = c_comdef_server::GetDatabaseVersion(); - $availableFields = ""; - $keys = c_comdef_meeting::GetFullTemplate(); - $meeting_time_zones_enabled = $localStrings['meeting_time_zones_enabled'] ? '1' : '0'; - $phpVersion = phpversion(); - - foreach ($keys as $key) { - if (($key['visibility'] != 1) && ($key['key'] != 'published') && ($key['key'] != 'shared_group_id_bigint')) { - if ($availableFields != "") { - $availableFields .= ','; - } - - $availableFields .= $key['key']; - } - } - - $ret = '"version","versionInt","langs","nativeLang","centerLongitude","centerLatitude","centerZoom","defaultDuration","regionBias","charSet","distanceUnits","semanticAdmin","emailEnabled","emailIncludesServiceBodies","changesPerMeeting","meeting_states_and_provinces","meeting_counties_and_sub_provinces","available_keys","google_api_key","dbVersion","dbPrefix","meeting_time_zones_enabled","phpVersion"'."\n"; - $ret .= '"'.$version_string.'","'.strval($version_num).'","'.$lang_string.'","'.$default_lang.'",'; - $ret .= '"'.strval($localStrings['search_spec_map_center']['longitude']).'","'.strval($localStrings['search_spec_map_center']['latitude']).'",'; - $ret .= '"'.strval($localStrings['search_spec_map_center']['zoom']).'","'.$localStrings['default_duration_time'].'",'; - $ret .= '"'.$localStrings['region_bias'].'","'.$localStrings['charset'].'","'.$localStrings['dist_units'].'","'.$canAdmin.'",'; - $ret .= '"'.$canEmail.'","'.$includeServiceBodiesOnEmails.'","'.$changeDepth.'","'.implode(',', $localStrings['meeting_states_and_provinces']).'","'.implode(',', $localStrings['meeting_counties_and_sub_provinces']).'","'.str_replace('"', '\"', $availableFields).',root_server_uri,format_shared_id_list","'.$localStrings['google_api_key'].'","'.$dbVersion.'","'.$localStrings['dbPrefix'].'","'.$meeting_time_zones_enabled.'","'.$phpVersion.'"'; - - return $ret; -} - -/*******************************************************************/ -/** - \brief Returns the server version in an array. - - \returns an array of integers, with [0] being the main version, [1] being the minor version, and [2] being the fix version. -*/ -function GetServerVersion() -{ - - $ret = explode('.', config()->get('app.version')); - - if (!isset($ret[1])) { - $ret[1] = '0'; - } - - if (!isset($ret[2])) { - $ret[1] = '0'; - } - - $ret[0] = intval($ret[0]); - $ret[1] = intval($ret[1]); - $ret[2] = intval($ret[2]); - - return $ret; -} - -/*******************************************************************/ -/** - \brief This returns change records. - - \returns CSV data, with the first row a key header. -*/ -function GetChanges( - $in_http_vars, ///< The HTTP GET/POST query. - $in_start_date = null, ///< Optional. A start date (In PHP time() format). If supplied, then only changes on, or after this date will be returned. - $in_end_date = null, ///< Optional. An end date (In PHP time() format). If supplied, then only changes that occurred on, or before this date will be returned. - $in_meeting_id = null, ///< Optional. If supplied, an ID for a particular meeting. Only changes for that meeting will be returned. - $in_sb_id = null ///< Optional. If supplied, an ID for a particular Service body. Only changes for that Service body will be returned. -) { - $ret = null; - - try { - $change_objects = c_comdef_server::GetChangesFromIDAndType('c_comdef_meeting', null, $in_start_date, $in_end_date); - if ($change_objects instanceof c_comdef_changes) { - $obj_array = $change_objects->GetChangesObjects(); - - if (is_array($obj_array) && count($obj_array)) { - set_time_limit(max(30, intval(count($obj_array) / 20))); // Change requests can take a loooong time... - $localized_strings = c_comdef_server::GetLocalStrings(); - include(dirname(__FILE__).'/../../server/config/get-config.php'); - $ret = '"date_int","date_string","change_type","change_id","meeting_id","meeting_name","user_id","user_name","service_body_id","service_body_name","meeting_exists","details","json_data"'."\n"; - - // If they specify a Service body, we also look in "child" Service bodies, so we need to produce a flat array of IDs. - if (isset($in_sb_id) && $in_sb_id) { - global $bmlt_array_gather; - - $bmlt_array_gather = array(); - - /************************************************//** - * This little internal function will simply fill * - * the $bmlt_array_gather array with a linear set of * - * Service body IDs that can be used for a quick * - * comparison, later on. It is a callback function. * - ****************************************************/ - function bmlt_at_at( - $in_value, - $in_key - ) { - global $bmlt_array_gather; - - if ($in_value instanceof c_comdef_service_body) { - array_push($bmlt_array_gather, $in_value->GetID()); - } - } - $tmp = c_comdef_server::GetServer()->GetNestedServiceBodyArray($in_sb_id); - array_walk_recursive($tmp, 'bmlt_at_at'); - - if (is_array($bmlt_array_gather) && count($bmlt_array_gather)) { - $in_sb_id = $bmlt_array_gather; - } else { - $in_sb_id = array ( $in_sb_id ); - } - } - - foreach ($obj_array as $change) { - $change_type = $change->GetChangeType(); - $date_int = intval($change->GetChangeDate()); - $change_id = intval($change->GetID()); - $date_string = date($change_date_format, $date_int); - $json_data = ''; - - if ($change instanceof c_comdef_change) { - $b_obj = $change->GetBeforeObject(); - $a_obj = $change->GetAfterObject(); - $meeting_id = intval($change->GetBeforeObjectID()); - $sb_a = intval(($a_obj instanceof c_comdef_meeting) ? $a_obj->GetServiceBodyID() : 0); - $sb_b = intval(($b_obj instanceof c_comdef_meeting) ? $b_obj->GetServiceBodyID() : 0); - $sb_c = intval($change->GetServiceBodyID()); - - if (!$meeting_id) { - $meeting_id = intval($change->GetAfterObjectID()); - } - - if ((intval($in_meeting_id) && intval($in_meeting_id) == intval($meeting_id)) || !intval($in_meeting_id)) { - $meeting_name = ''; - $user_name = ''; - - if (!is_array($in_sb_id) || !count($in_sb_id) || in_array($sb_a, $in_sb_id) || in_array($sb_b, $in_sb_id) || in_array($sb_c, $in_sb_id)) { - $sb_id = (intval($sb_c) ? $sb_c : (intval($sb_b) ? $sb_b : $sb_a)); - $meeting = (null != $b_obj) ? $b_obj : $a_obj; - - // Using str_replace, because preg_replace is pretty expensive. However, I don't think this buys us much. - if ($b_obj instanceof c_comdef_meeting) { - $meeting_name = str_replace('"', "'", str_replace("\n", " ", str_replace("\r", " ", $b_obj->GetMeetingDataValue('meeting_name')))); - } elseif ($a_obj instanceof c_comdef_meeting) { - $meeting_name = str_replace('"', "'", str_replace("\n", " ", str_replace("\r", " ", $a_obj->GetMeetingDataValue('meeting_name')))); - } - - $user_id = intval($change->GetUserID()); - - $user = c_comdef_server::GetUserByIDObj($user_id); - - if ($user instanceof c_comdef_user) { - $user_name = htmlspecialchars($user->GetLocalName()); - } - - $sb = c_comdef_server::GetServiceBodyByIDObj($sb_id); - - if ($sb instanceof c_comdef_service_body) { - $sb_name = htmlspecialchars($sb->GetLocalName()); - } - - $meeting_exists = 0; - - if (c_comdef_server::GetOneMeeting($meeting_id, true)) { - $meeting_exists = 1; - } - - $details = ''; - $desc = $change->DetailedChangeDescription(); - - if ($desc && isset($desc['details']) && is_array($desc['details'])) { - // We need to prevent double-quotes, as they are the string delimiters, so we replace them with single-quotes. - $details = str_replace('"', "'", str_replace("\n", " ", str_replace("\r", " ", implode(" ", $desc['details'])))); - } - - $change_line = array(); - - if ($date_int) { - $change_line['date_int'] = $date_int; - } else { - $change_line['date_int'] = 0; - } - - if ($date_string) { - $change_line['date_string'] = $date_string; - } else { - $change_line['date_string'] = ''; - } - - if ($change_type) { - $change_line['change_type'] = $change_type; - } else { - $change_line['change_type'] = ''; - } - - if ($change_id) { - $change_line['change_id'] = $change_id; - } else { - $change_line['change_id'] = 0; - } - - if ($meeting_id) { - $change_line['meeting_id'] = $meeting_id; - } else { - $change_line['meeting_id'] = 0; - } - - if ($meeting_name) { - $change_line['meeting_name'] = $meeting_name; - } else { - $change_line['meeting_name'] = ''; - } - - if ($user_id) { - $change_line['user_id'] = $user_id; - } else { - $change_line['user_id'] = 0; - } - - if ($user_name) { - $change_line['user_name'] = $user_name; - } else { - $change_line['user_name'] = ''; - } - - if ($sb_id) { - $change_line['service_body_id'] = $sb_id; - } else { - $change_line['service_body_id'] = ''; - } - - if ($sb_name) { - $change_line['service_body_name'] = $sb_name; - } else { - $change_line['service_body_name'] = ''; - } - - $change_line['meeting_exists'] = $meeting_exists; - - if ($details) { - $change_line['details'] = $details; - } else { - $change_line['details'] = ''; - } - - $json_data = MakeJSONDataObject($b_obj, 'before'); - - if (($json_data != '') && ($a_obj instanceof c_comdef_meeting)) { - $json_data .= ','; - } - - $json_data .= MakeJSONDataObject($a_obj, 'after'); - - $change_line['json_data'] = '{'.str_replace('"', '"', $json_data).'}'; - - $ret .= '"'.implode('","', $change_line)."\"\n"; - } - } - } - } - } - } - } catch (Exception $e) { - } - - return $ret; -} - -/*******************************************************************/ -/** - \brief Converts a given c_comdef_meeting object to a JSON object string. - - \returns A string, containing the JSON Data. It is blank if no JSON Data. -*/ -function MakeJSONDataObject( - $in_meeting_object, ///< The c_comdef_meeting object to be converted. - $in_object_name ///< A name for the returned object. -) { - $json_data = ''; - - if ($in_meeting_object instanceof c_comdef_meeting) { - $keys = $in_meeting_object->GetMeetingDataKeys(); - - foreach ($keys as $key) { - if ($key) { - $value = $in_meeting_object->GetMeetingDataValue($key); - - if ($value) { - if ($key == 'formats') { - $val_temp = array(); - $values = $value; - - foreach ($values as $format) { - if ($format instanceof c_comdef_format) { - $val_temp[] = $format->GetKey(); - } - } - - $value = $val_temp; - } - - if (is_array($value)) { - if (count($value)) { - for ($c = 0; $c < count($value); $c++) { - $val = json_encode(trim($value[$c], '"')); - $val = str_replace('"', '"', $val); - $val = str_replace('&', '&', $val); - $val = trim(preg_replace("|\s+|", ' ', $val), '"'); - $value[$c] = trim($val, "\\"); - } - - if ($json_data) { - $json_data .= ','; - } - - $json_data .= '"'.$key.'":'.'["'.implode('","', $value).'"]'; - } - } else { - $value = trim($value, "\\"); - $value = preg_replace("|^\"\"|", "\""", $value); - $value = trim(json_encode($value), '"'); - $value = str_replace('"', '"', $value); - $value = str_replace('&', '&', $value); - $value = trim(preg_replace("|\s+|", ' ', $value), '\\'); - $value = trim($value, '"'); - if ($json_data) { - $json_data .= ','; - } - $json_data .= '"'.$key.'":"'.$value.'"'; - } - } - } - } - - if ($json_data && $in_object_name) { - $json_data = '"'.$in_object_name.'":{'.$json_data.'}'; - } - } - - return $json_data; -} - -/*******************************************************************/ -/** - \brief Handles no command supplied (error) - - \returns English error string (not XML). -*/ -function HandleDefault( - $in_http_vars ///< The HTTP GET and POST parameters. -) { - return "You must supply one of the following: 'switcher=GetSearchResults', 'switcher=GetFormats', 'switcher=GetChanges', 'switcher=GetNAWSDump', 'switcher=GetFieldKeys', 'switcher=GetFieldValues' or 'switcher=GetServiceBodies'."; -} - -/*******************************************************************/ -/** - \brief Handles no server available (error). - - \returns null; -*/ -function HandleNoServer() -{ - return null; -} - -/*******************************************************************/ -/** - \brief Translates CSV to JSON. - - \returns a JSON string, with all the data in the CSV. -*/ -function TranslateToJSON( - $in_csv_data ///< An array of CSV data, with the first element being the field names. -) { - $temp_keyed_array = array(); - $in_csv_data = explode("\n", $in_csv_data); - $keys = array_shift($in_csv_data); - $keys = explode("\",\"", trim($keys, '"')); - - foreach ($in_csv_data as $row) { - if ($row) { - $line = null; - $index = 0; - $row = explode('","', trim($row, '",')); - foreach ($row as $column) { - if (isset($column)) { - $key = $keys[$index++]; - $value = str_replace("\t", ',', trim($column)); - - if ($key == "json_data") { - $value = trim($value, '"'); - $value = str_replace('"', '"', $value); - } - - $line[$key] = $value; - } - } - array_push($temp_keyed_array, $line); - } - } - - $out_json_data = str_replace('\\\\"', '"', array2json($temp_keyed_array)); // HACK ALERT: TranslateToJSON does whacky things with my escaped quotes, so I undo that here. - - return $out_json_data; -} - -/*******************************************************************/ -/** - \brief Translates CSV to XML. - - \returns an XML string, with all the data in the CSV. -*/ -function TranslateToXML( - $in_csv_data ///< An array of CSV data, with the first element being the field names. -) { - $temp_keyed_array = array(); - $in_csv_data = explode("\n", $in_csv_data); - $keys = array_shift($in_csv_data); - $keys = rtrim(ltrim($keys, '"'), '",'); - $keys = preg_split('/","/', $keys); - - foreach ($in_csv_data as $row) { - if ($row) { - $line = null; - $index = 0; - $row_t = rtrim(ltrim($row, '"'), '",'); - $row_t = preg_split('/","/', $row_t); - foreach ($row_t as $column) { - if (isset($column)) { - $line[$keys[$index++]] = trim($column); - } - } - array_push($temp_keyed_array, $line); - } - } - - $out_xml_data = array2xml($temp_keyed_array, 'not_used', false); - // HACK ALERT: Undoing the poopiness done by TranslateToXML. - $out_xml_data = str_replace("&aamp;quot;", """, $out_xml_data); - $out_xml_data = str_replace("&quot;", """, $out_xml_data); - $out_xml_data = str_replace("\\"", """, $out_xml_data); - $out_xml_data = str_replace("&ququot;", """, $out_xml_data); - - return $out_xml_data; -} diff --git a/src/legacy/client_interface/csv/index.php b/src/legacy/client_interface/csv/index.php deleted file mode 100755 index c4ba991e4..000000000 --- a/src/legacy/client_interface/csv/index.php +++ /dev/null @@ -1,60 +0,0 @@ -/client_interface/csv/ - with the same parameters that you would send to an advanced search. The results - will be returned as a CSV file. - - This file can be called from other servers. - - This file is part of the Basic Meeting List Toolbox (BMLT). - - Find out more at: https://bmlt.app - - BMLT is free software: you can redistribute it and/or modify - it under the terms of the MIT License. - - BMLT is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - MIT License for more details. - - You should have received a copy of the MIT License along with this code. - If not, see . -*/ - -defined('BMLT_EXEC') or define('BMLT_EXEC', true); // This is a security verifier. Keeps files from being executed outside of the context -require_once(dirname(__FILE__).'/csv.php'); -try { - $server = c_comdef_server::MakeServer(); - $ret = null; - - if ($server instanceof c_comdef_server) { -// if ( !isset ( $_GET['dump_ind_formats'] ) ) -// { -// $_GET['dump_ind_formats'] = true; -// } - - $ret = parse_redirect($server); - if (isset($_GET['compress_output']) || isset($_POST['compress_output'])) { - if (zlib_get_coding_type() === false) { - ob_start("ob_gzhandler"); - } else { - header('Content-Type:text/csv; charset=UTF-8'); - ob_start(); - } - } else { - header('Content-Type:text/csv; charset=UTF-8'); - ob_start(); - } - echo $ret; - ob_end_flush(); - } else { - echo HandleNoServer(); - } -} catch (Exception $e) { - echo HandleNoServer(); -} diff --git a/src/legacy/client_interface/csv/search_results_csv.php b/src/legacy/client_interface/csv/search_results_csv.php deleted file mode 100755 index 921932934..000000000 --- a/src/legacy/client_interface/csv/search_results_csv.php +++ /dev/null @@ -1,1360 +0,0 @@ -. -*/ - -defined('BMLT_EXEC') or die('Cannot Execute Directly'); // Makes sure that this file is in the correct context. - -require_once(dirname(__FILE__).'/common_search.inc.php'); -require(dirname(__FILE__).'/../../server/config/get-config.php'); // Just to make sure we have an early copy. - -global $g_format_dictionary; ///< This is a dictionary used to translate formats to NAWS format. It uses the format shared IDs in the server's language. - -bmlt_populate_format_dictionary(); - -/// If you wish to override this, simply set this up in your /get-config.php file. That will supersede this. -/// Actually... this block of code never, ever gets hit because the above call to bmlt_populate_format_dictionary -/// will always set $g_format_dictionary. We should... probably remove it? -if (!isset($g_format_dictionary) || !is_array($g_format_dictionary) || !count($g_format_dictionary)) { - /// This is the default set. - /// The right side is the BMLT side, and the left side is the NAWS code. The left side should not be changed. - $g_format_dictionary = array ( - 'CPT' => null, - 'MED' => null, - 'QA' => null, - 'RA' => null, - 'BEG' => array(1), - 'BT' => array(3), - 'OPEN' => array(4), - 'CAN' => array(6), - 'CH' => array(5), - 'CW' => array(7), - 'DISC' => array(8), - 'GL' => array(10), - 'GP' => array(52), - 'IP' => array(12), - 'IW' => array(13), - 'JFT' => array(14), - 'LIT' => array(36), - 'M' => array(15), - 'CLOSED' => array(17), - 'NC' => array(16), - 'NS' => array(37), - 'SMOK' => array(25), - 'SPK' => array(22), - 'STEP' => array(27), - 'SWG' => array(23), - 'TOP' => array(29), - 'TRAD' => array(30), - 'VAR' => array(19), - 'W' => array(32), - 'WCHR' => array(33), - 'Y' => array(34) - ); -} - -/*******************************************************************/ -/** \brief This reads in the server format codes, and populates the - format dictionary with the NAWS IDs. -*/ -function bmlt_populate_format_dictionary() -{ - global $g_format_dictionary; ///< This is a dictionary used to translate formats to NAWS format. It uses the format shared IDs in the server's language. - - // first accumulate a local array of formats in $dict - $dict = []; - $server = c_comdef_server::MakeServer(); - $localized_strings = c_comdef_server::GetLocalStrings(); - $formats_array = c_comdef_server::GetServer()->GetFormatsObj()->GetFormatsArray(); - - foreach ($formats_array['en'] as $format) { - if ($format instanceof c_comdef_format) { - $world_id = $format->GetWorldID(); - $shared_id = $format->GetSharedID(); - if ($world_id && $shared_id) { - if (array_key_exists($world_id, $dict)) { - array_push($dict[$world_id], $shared_id); - } else { - $dict[$world_id] = array( $shared_id ); - } - } - } - } - // add all the formats in $dict to $g_format_dictionary, putting the preferred formats first (in the same - // order as in naws_export_formats_at_front) - $g_format_dictionary = []; - $local_strings = c_comdef_server::GetLocalStrings(); - $preferred = $local_strings['naws_export_formats_at_front']; - foreach ($preferred as $id) { - if (array_key_exists($id, $dict)) { - $g_format_dictionary[$id] = $dict[$id]; - } - } - foreach ($dict as $id => $val) { - if (!in_array($id, $preferred)) { - $g_format_dictionary[$id] = $dict[$id]; - } - } -} - -/*******************************************************************/ -/** \brief This function does a search, then builds a CSV result, - with each row being a meeting. The first row is a row of keys. - - \returns a string, containing CSV data, with the first row a key header. -*/ -function DisplaySearchResultsCSV( - $in_http_vars, - // The various HTTP GET and POST parameters. - // If this is defined and set to 'yes', then that means the client supports AJAX. - // - 'supports_ajax' - // We serve non-JavaScript content to clients that don't support AJAX, even if they support JavaScript. - // - // The values that are important to the list paging are: - // - 'page_num' - // This is a positive integer, specifying which page of results to display. - // - // - 'page_size' - // This is the number of meetings to list on one "page" of results. - // The search results are paged, so that a large search is broken - // into multiple pages of page_display_size results. - // - // - 'sort_key' - // This is the key to use for sorting. There are three possible values: - // - 'town' - // This is sorted by town, borough and neighborhood first, weekday and time second. - // - 'weekday' - // This is sorted by weekday first, town, borough and neighborhood second, then time - // - 'time' - // This is sorted by weekday first, time, second, then town, borough and neighborhood. - // - // - 'sort_dir' - // This is the direction of the sort. It can be one of the following: - // - 'asc' - // Ascending, from least to greatest. - // - 'desc' - // Descending, from greatest to least. - // - // These are used to specify a search: - // - // - 'services' - // This is an array of positive integers. - // This is interpreted as an array of integers. Each integer represents the ID of a Service Body. - // A positive integer means that the search will look specifically for meetings that contain that - // Service Body ID. - // If the integer is negative (preceded by a minus sign -), then the criteria will be to look - // for meetings that don't contain that ID. - // If no 'services' values are given, then the search will not use the Service Body field as a - // search criteria. - // - // - 'venue_types' - // This is an array of integers. - // This is interpreted as an array of integers. Each integer represents a Venue Type. - // A positive integer means that the search will look specifically for meetings that have that Venue Type. - // If the integer is negative (preceded by a minus sign -), then the criteria will be to look - // for meetings that don't have that Venue Type. - // If no 'venue_type' values are given, then the search will not use the Venue Type field as a - // search criteria. - // - // - 'weekdays' - // This is an array of positive integers ( 1-7). - // This is interpreted as an array of integers. Each integer represents a weekday (1 -> Sunday, 7 -> Saturday). - // A positive integer means that the search will look specifically for meetings that occur on that weekday. - // If the integer is negative (preceded by a minus sign -), then the criteria will be to look - // for meetings that don't occur on that weekday. - // If no 'weekdays' values are given, then the search will not use the weekday field as a - // search criteria. - // - // - 'formats' - // This is an array of positive integers. - // This is interpreted as an array of integers. Each integer represents a format shared ID. - // A format ID means that the search will look specifically for meetings that have that format. - // If the format is negative (preceded by a minus sign -), then the criteria will be to look - // for meetings that don't have that format. - // If no 'formats' values are given, then the search will not use the formats field as a - // search criteria. - // - // - 'langs' - // This is an array of 2-character strings. - // This is interpreted as an array of strings. Each string represents a language code, and is a 2-character string. - // A language string means that the search will look specifically for meetings that are in that language. - // If the language is preceded by a minus sign -, then the criteria will be to look - // for meetings that are not in that language. - // If no 'langs' values are given, then the search will not use the lang_enum field as a - // search criteria. - // - // - 'bmlt_search_type' - // This is set to 'advanced' if the search is an advanced one (we need to take more criteria into consideration). - // - // - 'advanced_formats' - // This is the formats array, but is only counted if the bmlt_search_type is set to 'advanced'. - // - // - 'advanced_service_bodies' - // This is the same, but for Service Bodies. - // - // - 'advanced_weekdays' - // ...and weekdays. - // - // - 'advanced_radius' - // ...and radius (in degrees) - // - // - advanced_mapmode - // If this is true (1), then the Advanced form is using its map. - // - // The following values specify a start time "window." The meeting must start on, or after StartsAfterH/M, and - // can start no later than StartsBeforeH/M - // - // - 'StartsAfterH' - // A positive integer between 0 and 23. The hour of the minimal start time for meetings, in military time. - // - 'StartsAfterM' - // A positive integer between 0 and 59. The minute of the minimal start time for meetings, in military time. - // - 'StartsBeforeH' - // A positive integer between 0 and 23. The hour of the maximal start time for meetings, in military time. - // - 'StartsBeforeM' - // A positive integer between 0 and 59. The minute of the maximal start time for meetings, in military time. - // - // The following values specify a time duration "window." The meeting can last no longer than MaxDurationH/M, - // and no less than MinDurationH/M. - // - // - 'MinDurationH' - // A positive integer. This is the number of hours in the minimal duration. - // - 'MinDurationM' - // A positive integer. This is the number of minutes in the minimal duration. - // - 'MaxDurationH' - // A positive integer. This is the number of hours in the maximal duration. - // - 'MaxDurationM' - // A positive integer. This is the number of minutes in the maximal duration. - // - // This is how meetings are located. We don't use address lookups. Instead, we geolocate the meetings via the - // longitude and latitude fields in each record. If you don't specify a geolocation, then the entire database - // is searched. If you do specify one, then only the portion within the radius is searched. - // - // - 'geo_width' - // A floating point number. This is the radius (not diameter) of the search, in MILES (not Kilometers). - // If this is negative, then it should be an integer, and that indicates an auto-radius is requested to - // find the number of meetings in the integer. - // - // - 'geo_width_km' - // A floating point number. This is the radius (not diameter) of the search, in KILOMETERS (not Miles). - // If this is negative, then it should be an integer, and that indicates an auto-radius is requested to - // find the number of meetings in the integer. - // - // - 'long_val' - // If one of the three radius specifiers is zero or undefined, this is ignored. - // This is a floating point number that specifies the longitude, in degrees, of the center of the search radius. - // - // - 'lat_val' - // If one of the three radius specifiers is zero or undefined, this is ignored. - // This is a floating point number that specifies the latitude, in degrees, of the center of the search radius. - // - // - 'SearchString' - // A string. If this is specified, then all the string fields of the meetings specified by the above criteria - // will be searched for the string. By default, if the language supports metaphone (sound like search), then - // that is used. - // - // - 'StringSearchIsAnAddress' - // A boolean. Nonzero means that the given string should not be checked against any of the fields in the meeting - // data. Instead, it is to be considered a submission to the Google Maps geocode, and will be used to determine - // a cernter point in a local search. - // - // - 'SearchStringAll' - // If nonzero, then all of the words in the search string will have to be matched for a meetings to qualify. - // - // - 'SearchStringExact' - // If nonzero, metaphone will not be used, and the spelling must be exact. - // - // - 'meeting_ids' - // An array of positive integers. Each integer is an ID of an individual meeting. If this is set, all other - // search criteria are ignored. - // - // - 'sort_keys' - // This is a comma-separated list of sort keys. The leftmost one will be the top priority, and the rightmost the lowest. - // The sort depth will be the number of keys. - // The direction will be assumed 'asc', unless 'desc' is one of the keys (it can be anywhere in the list). - // - // - 'simple_other_fields' - // Set this to '1' in order to prevent the server from separating values with the prompt separator. - &$return_array = null, ///< If this is supplied, then the result will be saved in this as an array. It must be an empty array, supplied by reference. - &$return_geocode = null, - // If this is supplied, the response will be an associative array, with the search center and radius. - // It will return: - // - 'radius' The radius of the search, in Km - // - 'longitude' The longitude of the search center - // - 'latitude' Th latitude of the search center - &$return_results = null, ///< If supplied, should point to an array that will be filled with the actual meeting objects that comprise the result. - $in_supress_hidden_concat = false, ///< If true, then hidden fields will not have their prompts encoded - $in_editor_only = false ///< If true, then only meetings for which the current logged-in user can edit/observe are returned. -) { - $ret = null; - require_once(dirname(__FILE__).'/c_comdef_meeting_search_manager.class.php'); - - $search_manager = new c_comdef_meeting_search_manager; - - if ($search_manager instanceof c_comdef_meeting_search_manager) { - $localized_strings = c_comdef_server::GetLocalStrings(); - - $lang_enum = c_comdef_server::GetServer()->GetLocalLang(); - - // This can be changed in the auto config. - include(dirname(__FILE__).'/../../server/config/get-config.php'); - - if (isset($in_http_vars['lang_enum']) && $in_http_vars['lang_enum']) { - $lang_enum = $in_http_vars['lang_enum']; - } - - if (!isset($in_http_vars['results_per_page'])) { - $in_http_vars['results_per_page'] = 0; - } - - if (isset($default_sort_key) && !isset($in_http_vars['sort_key']) && !isset($in_http_vars['sort_keys'])) { - $in_http_vars['sort_key'] = $default_sort_key; - } - - if ((!isset($in_http_vars['sort_dir']) || ( ($in_http_vars['sort_dir'] != 'desc') && ($in_http_vars['sort_dir'] != 'asc') ) ) && !isset($in_http_vars['sort_keys'])) { - $in_http_vars['sort_dir'] = 'asc'; - } - - SetUpSearch($search_manager, $in_http_vars); - - if (isset($in_http_vars['page_size'])) { - $search_manager->SetResultsPerPage($in_http_vars['page_size']); - } - - if (isset($in_http_vars['sort_dir'])) { - $sort_dir_desc = ($in_http_vars['sort_dir'] == "desc") ? true : false; - - if (isset($localized_strings['default_sorts']) && isset($in_http_vars['sort_key']) && isset($sort_dir_desc) && !isset($in_http_vars['sort_keys'])) { - $search_manager->SetSort($localized_strings['default_sorts'][$in_http_vars['sort_key']], $sort_dir_desc, 0); - } - } - - $search_manager->DoSearch(); - - $long = null; - $lat = null; - - if (isset($in_http_vars['long_val'])) { - $long = $in_http_vars['long_val']; - } - - if (isset($in_http_vars['lat_val'])) { - $lat = $in_http_vars['lat_val']; - } - - if (isset($in_http_vars['geo_width'])) { - $my_radius = $in_http_vars['geo_width']; - } elseif (isset($in_http_vars['geo_width_km'])) { - $my_radius = $in_http_vars['geo_width_km']; - } - - if (isset($my_radius) && ($my_radius < 0)) { - $my_radius = $search_manager->GetRadius($localized_strings['dist_units'] == 'mi'); - } - - if (isset($return_geocode)) { - $return_geocode = nil; - - if ($search_manager->GetRadius(false)) { - $return_geocode['radius'] = $search_manager->GetRadius(false); - $return_geocode['longitude'] = $search_manager->GetLongitude(); - $return_geocode['latitude'] = $search_manager->GetLatitude(); - } - } - - $num_pages = $search_manager->GetNumberOfPages(); - $num_results = $search_manager->GetNumberOfResults(); - - $page_no = 1; - - if (isset($in_http_vars['page_num']) && (0 < intval($in_http_vars['page_num']))) { - $page_no = intval($in_http_vars['page_num']); - } - - if (1 > intval($page_no)) { - $page_no = 1; - } - - if ($page_no > $num_pages) { - $page_no = $num_pages; - } - - $page_data = $search_manager->GetPageOfResults($page_no); - - if ($page_data instanceof c_comdef_meeting_search_manager) { - $keys = c_comdef_meeting::GetAllMeetingKeys(); - // This is a required one for data export. - if (!in_array('meeting_name', $keys)) { - $keys[] = 'meeting_name'; - } - - $keys[] = 'root_server_uri'; - $keys[] = 'format_shared_id_list'; - - $ret = '"'.join('","', $keys).'"'; - - $formats = c_comdef_server::GetServer()->GetFormatsObj(); - $formats_keys = array(); - $formats_keys_header = array(); - - $ret .= "\n"; - - $in_ar = $page_data->GetSearchResultsAsArray(); - - if (isset($return_results) && is_array($return_results)) { - $return_results = $in_ar; - } - - foreach ($in_ar as &$mtg_obj) { - $line = array(); - $formats_ar = $formats_keys; - - if ($mtg_obj instanceof c_comdef_meeting) { - if (!$in_editor_only || $mtg_obj->UserCanObserve()) { - $format_shared_id_list = array(); - $first = true; - foreach ($keys as $key) { - if (trim($key)) { - $val = $mtg_obj->GetMeetingDataValue($key); - - if (($key == 'meeting_name') && !$val) { // No meeting name results in a generic "NA Meeting" as the name. - $val = $localized_strings['comdef_server_admin_strings']['Value_Prompts']['generic']; - } - - if ($key == 'lang_enum' && isset($in_http_vars['lang_enum']) && $in_http_vars['lang_enum']) { - // Override the native lang_enum for the meeting with the requested language if present in http_vars - // (Does this ever matter??) - $val = $in_http_vars['lang_enum']; - } - - if (isset($val)) { - if (($key == 'formats')) { - if (is_array($val) && count($val)) { - $v_ar = array(); - foreach ($val as $format) { - if ($format instanceof c_comdef_format) { - // $format will be one of the meeting's formats in the native server language. If it's already - // in the correct language, just add its key to $v_ar and its id to $format_shared_id_list. - // Otherwise see if there is a version of the format in the other language (stored in $lang_enum). If there is, - // push the key for the format in the other language onto $v_ar instead. Note that the key might be different - // in different languages. If there isn't a version of the format in the other language, just skip it. - $id = $format->GetSharedID(); - if ($format->GetLocalLang() == $lang_enum) { - array_push($v_ar, $format->GetKey()); - array_push($format_shared_id_list, $id); - } else { - $fs = $formats->GetFormatsBySharedIDCode($id); - if (array_key_exists($lang_enum, $fs)) { - $localized_format = $fs[$lang_enum]; - array_push($v_ar, $localized_format->GetKey()); - array_push($format_shared_id_list, $id); - } - } - } - } - $val = join(',', $v_ar); - $val = preg_replace('|"|', '\\"', preg_replace('|[\r\n\t]+|', ' ', $val)); - } elseif (is_string($val)) { - $val = preg_replace('|"|', '\\"', preg_replace('|[\r\n\t]+|', ' ', $val)); - } - } - - if (($key == 'formats') && $val) { - $f_list = explode(',', $val); - - if (is_array($f_list) && count($f_list)) { - foreach ($f_list as $format) { - $formats_ar[$format] = 1; - } - } - } - - if ($val) { - if ($mtg_obj->IsItemHidden($key)) { - if ($mtg_obj->UserCanObserve()) { - if (!$in_supress_hidden_concat && !isset($in_http_vars['simple_other_fields'])) { - $val = preg_replace('|.*?\#\@\-\@\#|', '', $mtg_obj->GetMeetingDataValue($key)); // Strip out any old accidentally introduced separators. - $val = 'observer_only#@-@#'.$mtg_obj->GetMeetingDataPrompt($key).'#@-@#'.$val; - } - } else { - $val = ''; - } - } else { - switch ($key) { - // We don't do anything for the standard fields. - case 'distance_in_miles': - case 'distance_in_km': - case 'id_bigint': - case 'worldid_mixed': - case 'shared_group_id_bigint': - case 'service_body_bigint': - case 'weekday_tinyint': - case 'venue_type': - case 'start_time': - case 'duration_time': - case 'time_zone': - case 'formats': - case 'lang_enum': - case 'longitude': - case 'latitude': - case 'published': - case 'email_contact': - case 'meeting_name': - case 'location_text': - case 'location_info': - case 'location_street': - case 'location_city_subsection': - case 'location_neighborhood': - case 'location_municipality': - case 'location_sub_province': - case 'location_province': - case 'location_postal_code_1': - case 'location_nation': - case 'comments': - case 'virtual_meeting_link': - case 'virtual_meeting_additional_info': - case 'phone_meeting_number': - break; - - // The rest get the prompt/value treatment, unless otherwise requested. - default: - if ($val && !isset($in_http_vars['simple_other_fields'])) { - $val = preg_replace('|.*?\#\@\-\@\#|', '', $val); // Strip out any old accidentally introduced separators. - $val = $mtg_obj->GetMeetingDataPrompt($key).'#@-@#'.$val; - } - break; - } - } - } - } else { - $val = ''; - } - - $val = trim(preg_replace("|[\n\r]+|", "; ", $val)); - - $line[$key] = $val; - } - } - - if (!isset($line['duration_time']) || !$line['duration_time'] || ($line['duration_time'] == '00:00:00')) { - $line['duration_time'] = $localized_strings['default_duration_time']; - } - - if (isset($format_shared_id_list) && is_array($format_shared_id_list) && count($format_shared_id_list)) { - sort($format_shared_id_list); - $line['format_shared_id_list'] = implode(',', $format_shared_id_list); - } - - $line['root_server_uri'] = dirname(dirname(GetURLToMainServerDirectory(true))); - - if (is_array($line) && count($line)) { - if (is_array($return_array)) { - array_push($return_array, $line); - } - - $ret .= '"'.join('","', $line).'"'; - - $ret .= "\n"; - } - } - } - } - } - } - - return $ret; -} - -/********************************************************************/ -/* NAWS LIST GENERATION */ -/* The following functions are used to generate a CSV file that is */ -/* in a format suitable for NA World Services (NAWS). Because they */ -/* often change their format, it needs to be extremely flexible. */ -/* The heart is a "translator dictionary," that matches fields in a */ -/* standard meeting object to the fields expected by NAWS. If the */ -/* content of a dictionary entry is a function, then a translation */ -/* is done by calling a function. Otherwise, if the content is a */ -/* field name, the contents of that field are simply transferred */ -/* without interpretation. */ -/********************************************************************/ - -/*******************************************************************/ -/** - \brief Returns the CSV file in NAWS format - - \returns A string, consisting of a CSV file, in the format required by NAWS. -*/ -function ReturnNAWSFormatCSV( - $in_http_vars, ///< The HTTP GET and POST parameters. - &$server ///< A reference to an instance of c_comdef_server -) { - // This is a dictionary that is used to translate the meeting data from the BMLT format to the NAWS format. - $transfer_dictionary = array( 'Committee' => 'BMLT_FuncNAWSReturnMeetingNAWSID', - 'CommitteeName' => 'meeting_name', - 'AddDate' => null, - 'AreaRegion' => 'BMLT_FuncNAWSReturnMeetingServiceBodyNAWSID', - 'ParentName' => 'BMLT_FuncNAWSReturnMeetingServiceBodyName', - 'ComemID' => null, - 'ContactID' => null, - 'ContactName' => null, - 'CompanyName' => null, - 'ContactAddrID' => null, - 'ContactAddress1' => null, - 'ContactAddress2' => null, - 'ContactCity' => null, - 'ContactState' => null, - 'ContactZip' => null, - 'ContactCountry' => null, - 'ContactPhone' => null, - 'MeetingID' => null, - 'Room' => 'BMLT_FuncNAWSReturnNonNawsFormats', - 'Closed' => 'BMLT_FuncNAWSReturnOpenOrClosed', - 'WheelChr' => 'BMLT_FuncNAWSReturnWheelchair', - 'Day' => 'BMLT_FuncNAWSReturnWeekday', - 'Time' => 'BMLT_FuncNAWSReturnTime', - 'Language1' => 'BMLT_FuncNAWSReturnLanguage1', - 'Language2' => null, - 'Language3' => null, - 'LocationId' => null, - 'Place' => 'location_text', - 'Address' => 'location_street', - 'City' => 'BMLT_FuncNAWSReturnMeetingTown', - 'LocBorough' => 'location_neighborhood', - 'State' => 'location_province', - 'Zip' => 'location_postal_code_1', - 'Country' => 'location_nation', - 'Directions' => 'BMLT_FuncNAWSReturnDirections', - 'Institutional' => 'BMLT_FuncNAWSReturnInst', - 'Format1' => 'BMLT_FuncNAWSReturnFormat1', - 'Format2' => 'BMLT_FuncNAWSReturnFormat2', - 'Format3' => 'BMLT_FuncNAWSReturnFormat3', - 'Format4' => 'BMLT_FuncNAWSReturnFormat4', - 'Format5' => 'BMLT_FuncNAWSReturnFormat5', - 'Delete' => null, - 'LastChanged' => 'BMLT_FuncNAWSReturnLastMeetingChangeTime', - 'Longitude' => 'longitude', - 'Latitude' => 'latitude', - 'ContactGP' => null, - 'PhoneMeetingNumber' => 'phone_meeting_number', - 'VirtualMeetingLink' => 'virtual_meeting_link', - 'VirtualMeetingInfo' => 'virtual_meeting_additional_info', - 'TimeZone' => 'time_zone', - 'bmlt_id' => 'id_bigint', - 'unpublished' => 'BMLT_FuncNAWSReturnPublishedStatus' - ); - - $ret = null; - - if (!( isset($in_http_vars['geo_width']) && $in_http_vars['geo_width'] ) && isset($in_http_vars['bmlt_search_type']) && ($in_http_vars['bmlt_search_type'] == 'advanced') && isset($in_http_vars['advanced_radius']) && isset($in_http_vars['advanced_mapmode']) && $in_http_vars['advanced_mapmode'] && ( floatval($in_http_vars['advanced_radius'] != 0.0) ) && isset($in_http_vars['lat_val']) && isset($in_http_vars['long_val']) && ( (floatval($in_http_vars['lat_val']) != 0.0) || (floatval($in_http_vars['long_val']) != 0.0) )) { - $in_http_vars['geo_width'] = $in_http_vars['advanced_radius']; - } elseif (!( isset($in_http_vars['geo_width']) && $in_http_vars['geo_width'] ) && isset($in_http_vars['bmlt_search_type']) && ($in_http_vars['bmlt_search_type'] == 'advanced')) { - $in_http_vars['lat_val'] = null; - $in_http_vars['long_val'] = null; - } elseif (!isset($in_http_vars['geo_loc']) || $in_http_vars['geo_loc'] != 'yes') { - if (!isset($in_http_vars['geo_width'])) { - $in_http_vars['geo_width'] = 0; - } - } - $ret_array = array (); // If we supply an array as a second parameter, we will get the dump returned in a two-dimensional array. - DisplaySearchResultsCSV($in_http_vars, $ret_array); // Start off by getting the CSV dump in the same manner as the normal CSV dump. - - if (is_array($ret_array) && count($ret_array)) { - $ret = '"'.join('","', array_keys($transfer_dictionary)).'"'; // This is the header line. - foreach ($ret_array as $one_meeting) { - if (is_array($one_meeting) && count($one_meeting)) { - $line = array(); - foreach ($transfer_dictionary as $key => $value) { - // See if this is a function. - if (function_exists($value) && is_callable($value) && preg_match('|^BMLT_FuncNAWSReturn|', $value)) { - $value = $value($one_meeting['id_bigint'], $server); - } elseif (isset($one_meeting[$value])) { // See if we just transfer the value with no change. - $value = $one_meeting[$value]; - } - array_push($line, $value); - } - - if (is_array($line) && count($line)) { - $ret .= "\n".'"'.join('","', $line).'"'; - } - } - } - } - - $del_meetings = ReturnNAWSDeletedMeetings($server, $transfer_dictionary, $in_http_vars['services']); // We append deleted meetings to the end. - - if (is_array($del_meetings) && count($del_meetings)) { - foreach ($del_meetings as $one_meeting) { - if (is_array($one_meeting) && count($one_meeting)) { - $ret .= "\n".'"'.join('","', $one_meeting).'"'; - } - } - } - - return $ret; -} - -/*******************************************************************/ -/** - \brief Returns deleted meetings with NAWS IDs. - - \description This queries every deleted meeting. The meetings returned are not restricted to the search parameters, - and may repeat from previous dumps. Only meetings that had World IDs, and that don't have the World ID 'deleted' - in their most recent change record, are returned. (The special World ID 'deleted' indicates a meeting that NAWS - has already processed, and so they don't need to see it again.) - - \returns An array of World IDs and change dates. These each represent deleted meetings. -*/ -function ReturnNAWSDeletedMeetings( - &$server, ///< A reference to an instance of c_comdef_server - $in_transfer_dictionary, ///< The transfer dictionary - $in_services ///< Any Service body IDs -) { - $ret = null; - $ids_to_ignore = []; // these are the IDs of meetings that NAWS has already processed, and so we don't output them - - // We start by getting all the meetings that have been deleted (Could be quite a few). - // These are returned in reverse chronological order, with the most recent change first. - $changes = $server->GetChangesFromOTypeAndCType('c_comdef_meeting', 'comdef_change_type_delete'); - - if ($changes instanceof c_comdef_changes) { - $ret = array(); - $c_array = $changes->GetChangesObjects(); - - if (is_array($c_array) && count($c_array)) { - foreach ($c_array as &$change) { - $b_obj = $change->GetBeforeObject(); - if ($b_obj instanceof c_comdef_meeting) { - $line = null; - if (!$server->GetOneMeeting($b_obj->GetID())) { // Must be currently deleted. - if (is_array($in_services) && count($in_services)) { - $found = false; - reset($in_services); - foreach ($in_services as $sb_id) { - if (!$found) { - if (intval($b_obj->GetServiceBodyID()) == intval($sb_id)) { - $found = true; - } - } - } - } - // If the meeting's ID is in $ids_to_ignore, we don't output it (not surprisingly). - // If the world_id for the meeting is 'deleted', that means that NAWS has already processed it, - // and we don't output it either; in addition, we add it to the $ids_to_ignore so that any earlier - // deletion change records for this meeting don't have anything output either. - if (in_array($b_obj->GetID(), $ids_to_ignore)) { - $value = false; - } else if (strtolower($b_obj->GetMeetingDataValue('worldid_mixed')) === 'deleted') { - array_push($ids_to_ignore, $b_obj->GetID()); - $value = false; - } else { - $value = intval(preg_replace('|\D*?|', '', $b_obj->GetMeetingDataValue('worldid_mixed'))); - } - - if ($value && $found) { - foreach ($in_transfer_dictionary as $key => $value2) { - if (($key != 'Delete')) { - $value1 = null; - // See if this is a function. - if (function_exists($value2) && is_callable($value2) && preg_match('|^BMLT_FuncNAWSReturn|', $value2)) { - if ($value2 == 'BMLT_FuncNAWSReturnLastMeetingChangeTime') { - $value1 = date('n/j/y', $change->GetChangeDate()); - } else { - $value1 = $value2($b_obj, $server); - } - } else // See if we just transfer the value with no change. - { - $value1 = $b_obj->GetMeetingDataValue($value2); - } - } else { - $value1 = 'D'; - } - - $line[$key] = $value1; - } - } - } - - array_push($ret, $line); - } - } - } - } - return $ret; -} - -/*******************************************************************/ -/** - \brief Returns '' or '1', if the meeting is unpublished or not (used for the NAWS format) - - \returns A string, '' or '1'. -*/ -function BMLT_FuncNAWSReturnPublishedStatus( - $in_meeting_id, ///< The ID of the meeting (internal DB ID). This can also be a meeting object. - &$server ///< A reference to an instance of c_comdef_server -) { - $ret = ''; - - if ($in_meeting_id instanceof c_comdef_meeting) { - $the_meeting = $in_meeting_id; - } else { - $the_meeting = $server->GetOneMeeting($in_meeting_id); - } - - if ($the_meeting instanceof c_comdef_meeting) { - $ret = $the_meeting->IsPublished() ? '' : '1'; - } - - return $ret; -} - -/*******************************************************************/ -/** - \brief Returns 'OPEN' or 'CLOSED', if the meeting is open or closed (used for the NAWS format) - - \returns A string, 'OPEN' or 'CLOSED'. -*/ -function BMLT_FuncNAWSReturnOpenOrClosed( - $in_meeting_id, ///< The ID of the meeting (internal DB ID). This can also be a meeting object. - &$server ///< A reference to an instance of c_comdef_server -) { - global $g_format_dictionary; - - $localized_strings = c_comdef_server::GetLocalStrings(); - - $ret = $localized_strings['default_closed_status'] ? 'CLOSED' : 'OPEN'; // This is the default closed/open status. - $opposite = $localized_strings['default_closed_status'] ? 'OPEN' : 'CLOSED'; - - if ($in_meeting_id instanceof c_comdef_meeting) { - $the_meeting = $in_meeting_id; - } else { - $the_meeting = $server->GetOneMeeting($in_meeting_id); - } - - $ids = $g_format_dictionary[$opposite]; - - if ($the_meeting instanceof c_comdef_meeting) { - $formats = $the_meeting->GetMeetingDataValue('formats'); - - if (is_array($formats) && count($formats) && is_array($ids)) { - foreach ($ids as $id) { - if (isset($formats[$id])) { - $ret = $opposite; - break; - } - } - } - } - - return $ret; -} - -/*******************************************************************/ -/** - \brief Returns 'TRUE' or 'FALSE', if the meeting is or is not wheelchair-accessible (used for the NAWS format) - - \returns A string, 'TRUE' or 'FALSE'. -*/ -function BMLT_FuncNAWSReturnWheelchair( - $in_meeting_id, ///< The ID of the meeting (internal DB ID) This can also be a meeting object. - &$server ///< A reference to an instance of c_comdef_server -) { - global $g_format_dictionary; - - $ret = 'FALSE'; - - if ($in_meeting_id instanceof c_comdef_meeting) { - $the_meeting = $in_meeting_id; - } else { - $the_meeting = $server->GetOneMeeting($in_meeting_id); - } - - $ids = $g_format_dictionary['WCHR']; - - if ($the_meeting instanceof c_comdef_meeting) { - $formats = $the_meeting->GetMeetingDataValue('formats'); - - if (is_array($formats) && count($formats) && is_array($ids)) { - foreach ($ids as $id) { - if (isset($formats[$id])) { - $ret = 'TRUE'; - break; - } - } - } - } - - return $ret; -} - -/*******************************************************************/ -/** - \brief Returns 'TRUE' or 'FALSE', if the meeting is or is not an institution meeting (used for the NAWS format) - - \returns A string, 'TRUE' or 'FALSE' (It will always be FALSE). -*/ -function BMLT_FuncNAWSReturnInst( - $in_meeting_id, ///< The ID of the meeting (internal DB ID) This can also be a meeting object. - &$server ///< A reference to an instance of c_comdef_server -) { - $ret = 'FALSE'; - - return $ret; -} - -/*******************************************************************/ -/** - \brief Returns the string for the weekday the meeting gathers (used for the NAWS format) - - \returns A string ('Monday' - 'Friday'). -*/ -function BMLT_FuncNAWSReturnWeekday( - $in_meeting_id, ///< The ID of the meeting (internal DB ID) This can also be a meeting object. - &$server ///< A reference to an instance of c_comdef_server -) { - $ret = null; - - $weekdays = array ( null, 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday' ); - - if ($in_meeting_id instanceof c_comdef_meeting) { - $the_meeting = $in_meeting_id; - } else { - $the_meeting = $server->GetOneMeeting($in_meeting_id); - } - - if ($the_meeting instanceof c_comdef_meeting) { - $ret = $weekdays[$the_meeting->GetMeetingDataValue('weekday_tinyint')]; - } - - return $ret; -} - -/*******************************************************************/ -/** - \brief Returns the string for the weekday the meeting gathers (used for the NAWS format) - - \returns A string (the time, in pure military time - no seconds). -*/ -function BMLT_FuncNAWSReturnTime( - $in_meeting_id, ///< The ID of the meeting (internal DB ID) This can also be a meeting object. - &$server ///< A reference to an instance of c_comdef_server -) { - $ret = null; - - if ($in_meeting_id instanceof c_comdef_meeting) { - $the_meeting = $in_meeting_id; - } else { - $the_meeting = $server->GetOneMeeting($in_meeting_id); - } - - if ($the_meeting instanceof c_comdef_meeting) { - $ret = explode(':', $the_meeting->GetMeetingDataValue('start_time')); - if (is_array($ret) && count($ret) > 1) { - $ret = $ret[0].$ret[1]; - } - } - - return $ret; -} - -/*******************************************************************/ -/** - \brief Returns the string for the first alternative language (if any) - - \returns A string. -*/ -function BMLT_FuncNAWSReturnLanguage1( - $in_meeting_id, ///< The ID of the meeting (internal DB ID) This can also be a meeting object. - &$server ///< A reference to an instance of c_comdef_server -) { - $ret = ''; - - if ($in_meeting_id instanceof c_comdef_meeting) { - $the_meeting = $in_meeting_id; - } else { - $the_meeting = $server->GetOneMeeting($in_meeting_id); - } - - if ($the_meeting instanceof c_comdef_meeting) { - $formats = $the_meeting->GetMeetingDataValue('formats'); - $lang = $server->GetLocalLang(); - - if (is_array($formats) && count($formats)) { - foreach ($formats as $format) { - if ($format instanceof c_comdef_format) { - if ('LANG' == $format->GetWorldID()) { - $ret = strtoupper(trim($format->GetKey())); - break; - } - } - } - } - } - - return $ret; -} - -/*******************************************************************/ -/** - \brief Returns the string for the NAWS ID for the meeting (used for the NAWS format) - - \returns A string The meeting ID, in NAWS form (G0000000). -*/ -function BMLT_FuncNAWSReturnMeetingNAWSID( - $in_meeting_id, ///< The ID of the meeting (internal DB ID) This can also be a meeting object. - &$server ///< A reference to an instance of c_comdef_server -) { - $ret = null; - if ($in_meeting_id instanceof c_comdef_meeting) { - $the_meeting = $in_meeting_id; - } else { - $the_meeting = $server->GetOneMeeting($in_meeting_id); - } - - if ($the_meeting instanceof c_comdef_meeting) { - $ret = trim($the_meeting->GetMeetingDataValue('worldid_mixed')); - } - - return $ret; -} - -/*******************************************************************/ -/** - \brief Returns the string for the town field the meeting (used for the NAWS format). This may use the borough name, instead. - - \returns A string The meeting town. -*/ -function BMLT_FuncNAWSReturnMeetingTown( - $in_meeting_id, ///< The ID of the meeting (internal DB ID) This can also be a meeting object. - &$server ///< A reference to an instance of c_comdef_server -) { - $ret = null; - if ($in_meeting_id instanceof c_comdef_meeting) { - $the_meeting = $in_meeting_id; - } else { - $the_meeting = $server->GetOneMeeting($in_meeting_id); - } - - if ($the_meeting instanceof c_comdef_meeting) { - // Our first choice is the borough/ku. - $ret = trim($the_meeting->GetMeetingDataValue('location_city_subsection')); - - if (!$ret) { - $ret = trim($the_meeting->GetMeetingDataValue('location_municipality')); - } - - // If all else fails, we use the neighborhood. - if (!$ret) { - $ret = trim($the_meeting->GetMeetingDataValue('location_neighborhood')); - } - } - - return $ret; -} - -/*******************************************************************/ -/** - \brief Returns the latest changed date for the given meeting. - - \returns a date in ISO form ('2013-01-31'). -*/ -function BMLT_FuncNAWSReturnLastMeetingChangeTime( - $in_meeting_id, ///< The ID of the meeting (internal DB ID) This can also be a meeting object. - &$server ///< A reference to an instance of c_comdef_server -) { - $ret = null; - - $changes_obj = $server->GetChangesFromIDAndType('c_comdef_meeting', $in_meeting_id); - - if ($changes_obj instanceof c_comdef_changes) { - $changes_objects = $changes_obj->GetChangesObjects(); - - if (is_array($changes_objects) && count($changes_objects)) { - $last_date = 0; - foreach ($changes_objects as $change) { - $last_date = max($last_date, $change->GetChangeDate()); - } - - if ($last_date) { - $ret = date('n/j/y', $last_date); - } - } - } - - return $ret; -} - -/*******************************************************************/ -/** - \brief Returns the string for the NAWS ID for the meeting's Service Body (used for the NAWS format) - - \returns A string The Service Body ID, in NAWS form (RG/AR0000000). -*/ -function BMLT_FuncNAWSReturnMeetingServiceBodyNAWSID( - $in_meeting_id, ///< The ID of the meeting (internal DB ID) This can also be a meeting object. - &$server ///< A reference to an instance of c_comdef_server -) { - $ret = null; - - if ($in_meeting_id instanceof c_comdef_meeting) { - $the_meeting = $in_meeting_id; - } else { - $the_meeting = $server->GetOneMeeting($in_meeting_id); - } - - if ($the_meeting instanceof c_comdef_meeting) { - $service_body = $the_meeting->GetServiceBodyObj(); - - $ret2 = intval(preg_replace('|\D*?|', '', trim($service_body->GetWorldID()))); - - if ($service_body instanceof c_comdef_service_body) { - if ($service_body->GetSBType() == c_comdef_service_body__ASC__) { - if ($ret2) { - $ret = sprintf('AR%05d', $ret2); - } - } elseif ($service_body->GetSBType() == c_comdef_service_body__RSC__) { - if ($ret2) { - $ret = sprintf('RG%03d', $ret2); - } - } - } - } - - return $ret; -} - -/*******************************************************************/ -/** -\brief Returns a string of all formats that don't map to NAWS codes. - -\returns A string The format codes name_string. - */ -function BMLT_FuncNAWSReturnNonNawsFormats( - $in_meeting_id, ///< The ID of the meeting (internal DB ID) This can also be a meeting object. - &$server ///< A reference to an instance of c_comdef_server -) { - - $ret = ""; - - if ($in_meeting_id instanceof c_comdef_meeting) { - $the_meeting = $in_meeting_id; - } else { - $the_meeting = $server->GetOneMeeting($in_meeting_id); - } - - if ($the_meeting instanceof c_comdef_meeting) { - $formats = $the_meeting->GetMeetingDataValue('formats'); - - if (is_array($formats) && count($formats)) { - foreach ($formats as $format) { - if ($format != null && !$format->GetWorldID()) { - $ret .= $format->GetLocalName(); - $ret .= ','; - } - } - - $ret = rtrim($ret, ','); - } - } - - return $ret; -} - -/*******************************************************************/ -/** -\brief Returns a string of location_info and comments fields. - -\returns A string The location_info and comments fields. - */ -function BMLT_FuncNAWSReturnDirections( - $in_meeting_id, ///< The ID of the meeting (internal DB ID) This can also be a meeting object. - &$server ///< A reference to an instance of c_comdef_server -) { - - $ret = ""; - - if ($in_meeting_id instanceof c_comdef_meeting) { - $the_meeting = $in_meeting_id; - } else { - $the_meeting = $server->GetOneMeeting($in_meeting_id); - } - - if ($the_meeting instanceof c_comdef_meeting) { - $ret = trim($the_meeting->GetMeetingDataValue('location_info')); - - if ($the_meeting->GetMeetingDataValue('comments')) { - if ($ret) { - $ret .= ", "; - } - $ret .= trim($the_meeting->GetMeetingDataValue('comments')); - } - } - - return $ret; -} - -/*******************************************************************/ -/** - \brief Returns the string for the first format (used for the NAWS format) - - \returns A string The format code, in NAWS form. -*/ -function BMLT_FuncNAWSReturnFormat1( - $in_meeting_id, ///< The ID of the meeting (internal DB ID) This can also be a meeting object. - &$server ///< A reference to an instance of c_comdef_server -) { - return BMLT_FuncNAWSReturnFormat(1, $in_meeting_id, $server); -} - -/*******************************************************************/ -/** - \brief Returns the string for the second format (used for the NAWS format) - - \returns A string The format code, in NAWS form. -*/ -function BMLT_FuncNAWSReturnFormat2( - $in_meeting_id, ///< The ID of the meeting (internal DB ID) This can also be a meeting object. - &$server ///< A reference to an instance of c_comdef_server -) { - return BMLT_FuncNAWSReturnFormat(2, $in_meeting_id, $server); -} - -/*******************************************************************/ -/** - \brief Returns the string for the third format (used for the NAWS format) - - \returns A string The format code, in NAWS form. -*/ -function BMLT_FuncNAWSReturnFormat3( - $in_meeting_id, ///< The ID of the meeting (internal DB ID) This can also be a meeting object. - &$server ///< A reference to an instance of c_comdef_server -) { - return BMLT_FuncNAWSReturnFormat(3, $in_meeting_id, $server); -} - -/*******************************************************************/ -/** - \brief Returns the string for the fourth format (used for the NAWS format) - - \returns A string The format code, in NAWS form. -*/ -function BMLT_FuncNAWSReturnFormat4( - $in_meeting_id, ///< The ID of the meeting (internal DB ID) This can also be a meeting object. - &$server ///< A reference to an instance of c_comdef_server -) { - return BMLT_FuncNAWSReturnFormat(4, $in_meeting_id, $server); -} - -/*******************************************************************/ -/** - \brief Returns the string for the fifth format (used for the NAWS format) - - \returns A string The format code, in NAWS form. -*/ -function BMLT_FuncNAWSReturnFormat5( - $in_meeting_id, ///< The ID of the meeting (internal DB ID) This can also be a meeting object. - &$server ///< A reference to an instance of c_comdef_server -) { - return BMLT_FuncNAWSReturnFormat(5, $in_meeting_id, $server); -} - -/*******************************************************************/ -/** - \brief Returns the string for the n-th format (used for the NAWS format) - - \returns A string The format code, in NAWS form. - */ -function BMLT_FuncNAWSReturnFormat( - $n, ///< which format - $in_meeting_id, ///< The ID of the meeting (internal DB ID) This can also be a meeting object. - &$server ///< A reference to an instance of c_comdef_server -) { - global $g_format_dictionary; - if ($in_meeting_id instanceof c_comdef_meeting) { - $the_meeting = $in_meeting_id; - } else { - $the_meeting = $server->GetOneMeeting($in_meeting_id); - } - if ($the_meeting instanceof c_comdef_meeting) { - // $formats is an array of the formats for this meeting as they are stored in the BMLT database. - // $naws_formats is an array of the NAWS versions of these formats - note that not everything in $formats - // will have a corresponding NAWS versions. Also there can also be several BMLT formats that map - // to the same NAWS format -- in this case, only include one NAWS format. - // This function is a bit stupid, since it gets called up to 5 times for the 5 possible NAWS formats -- - // more aesthetic (and slightly more efficient) would be to just call it once. However, efficiency is not - // terribly important here since this just gets called when producing an export spreadsheet. - $formats = $the_meeting->GetMeetingDataValue('formats'); - $naws_formats = []; - if (is_array($formats) && count($formats)) { - foreach ($g_format_dictionary as $n_format => $b_formats) { - if (($n_format != 'OPEN') && ($n_format != 'CLOSED') && ($n_format != 'WCHR')) { - foreach ($b_formats as $b_format) { - if (isset($formats[$b_format]) && !in_array($n_format, $naws_formats)) { - array_push($naws_formats, $n_format); - } - } - } - } - } - if ($n > count($naws_formats)) { - return null; - } else { - return $naws_formats[$n-1]; - } - } -} - -/*******************************************************************/ -/** - \brief Returns the string for the name for the meeting's Service Body (used for the NAWS format) - - \returns A string The Service Body name. -*/ -function BMLT_FuncNAWSReturnMeetingServiceBodyName( - $in_meeting_id, ///< The ID of the meeting (internal DB ID) This can also be a meeting object. - &$server ///< A reference to an instance of c_comdef_server -) { - $ret = null; - - if ($in_meeting_id instanceof c_comdef_meeting) { - $the_meeting = $in_meeting_id; - } else { - $the_meeting = $server->GetOneMeeting($in_meeting_id); - } - - if ($the_meeting instanceof c_comdef_meeting) { - $service_body = $the_meeting->GetServiceBodyObj(); - - while (!$ret && ($service_body instanceof c_comdef_service_body)) { - if (($service_body->GetSBType() == c_comdef_service_body__ASC__) || ($service_body->GetSBType() == c_comdef_service_body__RSC__)) { - $ret = $service_body->GetLocalName(); - } else { - $service_body = $service_body->GetOwnerIDObject(); - } - } - } - - return $ret; -} diff --git a/src/legacy/client_interface/gpx/index.php b/src/legacy/client_interface/gpx/index.php deleted file mode 100755 index 63f366057..000000000 --- a/src/legacy/client_interface/gpx/index.php +++ /dev/null @@ -1,64 +0,0 @@ -/client_interface/gpx/ - with the same parameters that you would send to an advanced search. The results - will be returned as an GPX file. - - This file can be called from other servers. - - This file is part of the Basic Meeting List Toolbox (BMLT). - - Find out more at: https://bmlt.app - - BMLT is free software: you can redistribute it and/or modify - it under the terms of the MIT License. - - BMLT is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - MIT License for more details. - - You should have received a copy of the MIT License along with this code. - If not, see . -*/ - -defined('BMLT_EXEC') or define('BMLT_EXEC', true); // This is a security verifier. Keeps files from being executed outside of the context -require_once(dirname(__FILE__).'/../csv/csv.php'); - -try { - $server = c_comdef_server::MakeServer(); - $ret = null; - - if ($server instanceof c_comdef_server) { - $_GET['switcher'] = 'GetSearchResults'; - unset($_GET['xml_data']); - $_GET['gpx_data'] = true; - $_GET['data_field_key'] = 'longitude,latitude,location_city_subsection,location_neighborhood,location_province,location_nation,location_postal_code_1,location_text,location_street,location_info,location_municipality,meeting_name,weekday_tinyint,start_time'; - $ret = parse_redirect($server); - // The caller can request compression. Not all clients can deal with compressed replies. - if (isset($_GET['compress_output']) || isset($_POST['compress_output'])) { - if (zlib_get_coding_type() === false) { - ob_start("ob_gzhandler"); - } else { - header('Content-Type:application/xml; charset=UTF-8'); - header('Content-Disposition: attachment; filename="SearchResults.gpx"'); - ob_start(); - } - } else { - header('Content-Type:application/xml; charset=UTF-8'); - header('Content-Disposition: attachment; filename="SearchResults.gpx"'); - ob_start(); - } - - echo $ret; - ob_end_flush(); - } else { - echo HandleNoServer(); - } -} catch (Exception $e) { - echo HandleNoServer(); -} diff --git a/src/legacy/client_interface/html/index.php b/src/legacy/client_interface/html/index.php deleted file mode 100755 index 38778c7e4..000000000 --- a/src/legacy/client_interface/html/index.php +++ /dev/null @@ -1,83 +0,0 @@ -my_server->GetLocalStrings(); -$user_obj = $console_object->my_server->GetCurrentUserObj(); -if ($user_obj instanceof c_comdef_user && $user_obj->GetUserLevel() != _USER_LEVEL_DEACTIVATED) { - $service_body_ids = []; - $service_body_set = []; - $user_level = intval($user_obj->GetUserLevel()); - if ($user_level === _USER_LEVEL_OBSERVER) { - $service_body_set = $console_object->my_observable_service_bodies; - } else if ($user_level === _USER_LEVEL_SERVICE_BODY_ADMIN) { - $service_body_set = $console_object->my_service_bodies; - } else if ($user_level === _USER_LEVEL_SERVER_ADMIN) { - $service_body_set = $console_object->my_all_service_bodies; - } - - foreach ($service_body_set as $service_body_id) { - array_push($service_body_ids, intval($service_body_id->GetID())); - } - - function getBCP47TagForISO631Language($code) - { - $default = 'en-US'; - - $iso630tobcp47 = [ - 'de' => 'de-DE', - 'dk' => 'da-DK', - 'es' => 'es-US', - 'fa' => 'fa-IR', - 'fr' => 'fr-CA', - 'it' => 'it-IT', - 'pl' => 'pl-PL', - 'pt' => 'pt-BR', - 'sv' => 'sv-SE' - ]; - - return array_key_exists($code, $iso630tobcp47) ? $iso630tobcp47[$code] : $default; - }?> - - - - - - cookie('bmlt_admin_lang_pref', 'en'); - ?> - " /> - " /> - - - - - -
-
- spinning loader -
-
- - - diff --git a/src/legacy/client_interface/index.htm b/src/legacy/client_interface/index.htm deleted file mode 100755 index e69de29bb..000000000 diff --git a/src/legacy/client_interface/json/GetLangs.php b/src/legacy/client_interface/json/GetLangs.php deleted file mode 100755 index 78923799a..000000000 --- a/src/legacy/client_interface/json/GetLangs.php +++ /dev/null @@ -1,66 +0,0 @@ -. -********************************************************************************************/ - -defined('BMLT_EXEC') or define('BMLT_EXEC', true); // This is a security verifier. Keeps files from being executed outside of the context -$file_dir = str_replace('/client_interface/json', '', dirname(__FILE__)).'/server/c_comdef_server.class.php'; -require_once($file_dir); -$server = c_comdef_server::MakeServer(); -$ret = null; - -if ($server instanceof c_comdef_server) { - $langs = $server->GetServerLangs(); - - if ($langs) { - // The caller can request compression. Not all clients can deal with compressed replies. - if (isset($_GET['compress_json']) || isset($_POST['compress_json'])) { - ob_start('ob_gzhandler'); - } else { - header('Content-Type:application/json; charset=UTF-8'); - ob_start(); - } - - echo '{"languages":['; - - $first = true; - - foreach ($langs as $key_string => $name_string) { - if (!$first) { - echo ","; - } else { - $first = false; - } - - echo '{"key":'.json_encode($key_string); - echo ',"name":'.json_encode($name_string); - if (!strcmp($key_string, $server->GetLocalLang())) { - echo ',"default":true'; - } - echo '}'; - } - - echo "]}"; - ob_end_flush(); - } else { - echo ( 'No Languages' ); - } -} else { - echo ( 'No Server' ); -} diff --git a/src/legacy/client_interface/json/index.php b/src/legacy/client_interface/json/index.php deleted file mode 100755 index 52cdc51af..000000000 --- a/src/legacy/client_interface/json/index.php +++ /dev/null @@ -1,58 +0,0 @@ -/client_interface/json/ - with the same parameters that you would send to an advanced search. The results - will be returned as a JSON file. - - This file can be called from other servers. - - This file is part of the Basic Meeting List Toolbox (BMLT). - - Find out more at: https://bmlt.app - - BMLT is free software: you can redistribute it and/or modify - it under the terms of the MIT License. - - BMLT is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - MIT License for more details. - - You should have received a copy of the MIT License along with this code. - If not, see . -*/ - -defined('BMLT_EXEC') or define('BMLT_EXEC', true); // This is a security verifier. Keeps files from being executed outside of the context - -require_once(dirname(__FILE__).'/../csv/csv.php'); - -try { - $server = c_comdef_server::MakeServer(); - $ret = null; - - if ($server instanceof c_comdef_server) { - $_GET['json_data'] = true; - $ret = parse_redirect($server); - if (isset($_GET['compress_output']) || isset($_POST['compress_output'])) { - if (zlib_get_coding_type() === false) { - ob_start("ob_gzhandler"); - } else { - ob_start(); - } - } else { - header('Content-Type:application/json; charset=UTF-8'); - ob_start(); - } - - echo $ret; - ob_end_flush(); - } else { - echo HandleNoServer(); - } -} catch (Exception $e) { - echo HandleNoServer(); -} diff --git a/src/legacy/client_interface/jsonp/GetLangs.php b/src/legacy/client_interface/jsonp/GetLangs.php deleted file mode 100755 index 3701b314b..000000000 --- a/src/legacy/client_interface/jsonp/GetLangs.php +++ /dev/null @@ -1,66 +0,0 @@ -. -********************************************************************************************/ - -defined('BMLT_EXEC') or define('BMLT_EXEC', true); // This is a security verifier. Keeps files from being executed outside of the context -$file_dir = str_replace('/client_interface/jsonp', '', dirname(__FILE__)).'/server/c_comdef_server.class.php'; -require_once($file_dir); -$server = c_comdef_server::MakeServer(); -$ret = null; - -if ($server instanceof c_comdef_server) { - $langs = $server->GetServerLangs(); - - if ($langs) { - // The caller can request compression. Not all clients can deal with compressed replies. - if (isset($_GET['compress_json']) || isset($_POST['compress_json'])) { - ob_start('ob_gzhandler'); - } else { - header('Content-Type:application/javascript; charset=UTF-8'); - ob_start(); - } - - echo $_GET['callback'] . '({"languages":['; - - $first = true; - - foreach ($langs as $key_string => $name_string) { - if (!$first) { - echo ","; - } else { - $first = false; - } - - echo '{"key":'.json_encode($key_string); - echo ',"name":'.json_encode($name_string); - if (!strcmp($key_string, $server->GetLocalLang())) { - echo ',"default":true'; - } - echo '}'; - } - - echo "]});"; - ob_end_flush(); - } else { - echo ( 'No Languages' ); - } -} else { - echo ( 'No Server' ); -} diff --git a/src/legacy/client_interface/jsonp/index.php b/src/legacy/client_interface/jsonp/index.php deleted file mode 100755 index 3c286dbc3..000000000 --- a/src/legacy/client_interface/jsonp/index.php +++ /dev/null @@ -1,60 +0,0 @@ -/client_interface/jsonp/ - with the same parameters that you would send to an advanced search. The results - will be returned as a JSONP file. - - This file can be called from other servers. - - This file is part of the Basic Meeting List Toolbox (BMLT). - - Find out more at: https://bmlt.app - - BMLT is free software: you can redistribute it and/or modify - it under the terms of the MIT License. - - BMLT is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - MIT License for more details. - - You should have received a copy of the MIT License along with this code. - If not, see . -*/ - -defined('BMLT_EXEC') or define('BMLT_EXEC', true); // This is a security verifier. Keeps files from being executed outside of the context - -require_once(dirname(__FILE__).'/../csv/csv.php'); - -try { - $server = c_comdef_server::MakeServer(); - $ret = null; - - if ($server instanceof c_comdef_server) { - $_GET['json_data'] = true; - $ret = parse_redirect($server); - if (isset($_GET['compress_output']) || isset($_POST['compress_output'])) { - if (zlib_get_coding_type() === false) { - ob_start("ob_gzhandler"); - } else { - ob_start(); - } - } else { - header('Content-Type:application/javascript; charset=UTF-8'); - ob_start(); - } - - echo $_GET['callback'] . '('; - echo $ret; - echo ');'; - ob_end_flush(); - } else { - echo HandleNoServer(); - } -} catch (Exception $e) { - echo HandleNoServer(); -} diff --git a/src/legacy/client_interface/kml/index.php b/src/legacy/client_interface/kml/index.php deleted file mode 100755 index 7943032e7..000000000 --- a/src/legacy/client_interface/kml/index.php +++ /dev/null @@ -1,65 +0,0 @@ -/client_interface/kml/ - with the same parameters that you would send to an advanced search. The results - will be returned as an KML file. - - This file can be called from other servers. - - This file is part of the Basic Meeting List Toolbox (BMLT). - - Find out more at: https://bmlt.app - - BMLT is free software: you can redistribute it and/or modify - it under the terms of the MIT License. - - BMLT is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - MIT License for more details. - - You should have received a copy of the MIT License along with this code. - If not, see . -*/ - -defined('BMLT_EXEC') or define('BMLT_EXEC', true); // This is a security verifier. Keeps files from being executed outside of the context -require_once(dirname(__FILE__).'/../csv/csv.php'); - -try { - $server = c_comdef_server::MakeServer(); - $ret = null; - - if ($server instanceof c_comdef_server) { - $_GET['switcher'] = 'GetSearchResults'; - unset($_GET['xml_data']); - unset($_GET['gpx_data']); - $_GET['kml_data'] = true; - $_GET['data_field_key'] = 'longitude,latitude,location_city_subsection,location_neighborhood,location_province,location_nation,location_postal_code_1,location_text,location_street,location_info,location_municipality,meeting_name,weekday_tinyint,start_time'; - $ret = parse_redirect($server); - // The caller can request compression. Not all clients can deal with compressed replies. - if (isset($_GET['compress_output']) || isset($_POST['compress_output'])) { - if (zlib_get_coding_type() === false) { - ob_start("ob_gzhandler"); - } else { - header('Content-Type:application/xml; charset=UTF-8'); - header('Content-Disposition: attachment; filename="SearchResults.kml"'); - ob_start(); - } - } else { - header('Content-Type:application/xml; charset=UTF-8'); - header('Content-Disposition: attachment; filename="SearchResults.kml"'); - ob_start(); - } - - echo $ret; - ob_end_flush(); - } else { - echo HandleNoServer(); - } -} catch (Exception $e) { - echo HandleNoServer(); -} diff --git a/src/legacy/client_interface/poi/index.php b/src/legacy/client_interface/poi/index.php deleted file mode 100755 index de68ab482..000000000 --- a/src/legacy/client_interface/poi/index.php +++ /dev/null @@ -1,66 +0,0 @@ -/client_interface/poi/ - with the same parameters that you would send to an advanced search. The results - will be returned as an POI CSV file. - - This file can be called from other servers. - - This file is part of the Basic Meeting List Toolbox (BMLT). - - Find out more at: https://bmlt.app - - BMLT is free software: you can redistribute it and/or modify - it under the terms of the MIT License. - - BMLT is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - MIT License for more details. - - You should have received a copy of the MIT License along with this code. - If not, see . -*/ - -defined('BMLT_EXEC') or define('BMLT_EXEC', true); // This is a security verifier. Keeps files from being executed outside of the context -require_once(dirname(__FILE__).'/../csv/csv.php'); - -try { - $server = c_comdef_server::MakeServer(); - $ret = null; - - if ($server instanceof c_comdef_server) { - $_GET['switcher'] = 'GetSearchResults'; - unset($_GET['xml_data']); - unset($_GET['gpx_data']); - unset($_GET['kml_data']); - $_GET['poi_data'] = true; - $_GET['data_field_key'] = 'longitude,latitude,location_city_subsection,location_neighborhood,location_province,location_nation,location_postal_code_1,location_text,location_street,location_info,location_municipality,meeting_name,weekday_tinyint,start_time'; - $ret = parse_redirect($server); - // The caller can request compression. Not all clients can deal with compressed replies. - if (isset($_GET['compress_output']) || isset($_POST['compress_output'])) { - if (zlib_get_coding_type() === false) { - ob_start("ob_gzhandler"); - } else { - header('Content-Type:text/csv; charset=UTF-8'); - header('Content-Disposition: attachment; filename="SearchResultsPOI.csv"'); - ob_start(); - } - } else { - header('Content-Type:text/csv; charset=UTF-8'); - header('Content-Disposition: attachment; filename="SearchResultsPOI.csv"'); - ob_start(); - } - - echo $ret; - ob_end_flush(); - } else { - echo HandleNoServer(); - } -} catch (Exception $e) { - echo HandleNoServer(); -} diff --git a/src/legacy/client_interface/simple/index.php b/src/legacy/client_interface/simple/index.php deleted file mode 100755 index 37e651f57..000000000 --- a/src/legacy/client_interface/simple/index.php +++ /dev/null @@ -1,515 +0,0 @@ -/client_interface/simple/ - with the same parameters that you would send to an advanced search. The results - will be returned as XHTML data. - - This file can be called from other servers. - - This file is part of the Basic Meeting List Toolbox (BMLT). - - Find out more at: https://bmlt.app - - BMLT is free software: you can redistribute it and/or modify - it under the terms of the MIT License. - - BMLT is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - MIT License for more details. - - You should have received a copy of the MIT License along with this code. - If not, see . -*/ -defined('BMLT_EXEC') or define('BMLT_EXEC', true); // This is a security verifier. Keeps files from being executed outside of the context -require_once(dirname(__FILE__).'/../../server/shared/classes/comdef_utilityclasses.inc.php'); -require_once(dirname(__FILE__).'/../csv/csv.php'); - -$server = c_comdef_server::MakeServer(); -$ret = null; - -if ($server instanceof c_comdef_server) { - /*******************************************************************/ - /** - \brief Queries the local server, and returns processes XHTML. - - This requires that the "switcher=" parameter be set in the GET or - POST parameters: - - 'GetSearchResults' - This returns the search results. - - \returns CSV data, with the first row a key header. - */ - function parse_redirect_simple( - &$server ///< A reference to an instance of c_comdef_server - ) { - $result = null; - $http_vars = array_merge_recursive($_GET, $_POST); - - if (!isset($http_vars['lang_enum']) || !$http_vars['lang_enum']) { - $http_vars['lang_enum'] = $server->GetLocalLang(); - } - - // Just to be safe, we override any root passed in. We know where our root is, and we don't need to be told. - $http_vars['bmlt_root'] = 'http://'.$_SERVER['SERVER_NAME'].(($_SERVER['SERVER_PORT'] != 80) ? ':'.$_SERVER['SERVER_PORT'] : '').dirname($_SERVER['SCRIPT_NAME'])."/../../"; - - switch ($http_vars['switcher']) { - case 'GetSearchResults': - $container = (isset($http_vars['container_id']) && $http_vars['container_id']) ? $http_vars['container_id'] : null; - $result = GetSimpleSearchResults($http_vars, isset($http_vars['block_mode']), $container); - break; - - case 'GetFormats': - $lang = null; - - if (isset($http_vars['lang_enum'])) { - $lang = $http_vars['lang_enum']; - } - - $formatKeyStrings = null; - if (isset($http_vars['key_strings']) && is_array($http_vars['key_strings']) && count($http_vars['key_strings'])) { - $formatKeyStrings = $http_vars['key_strings']; - } else if (isset($http_vars['key_strings'])) { - $formatKeyStrings = [$http_vars['key_strings']]; - } - - unset($http_vars['lang_enum']); - unset($http_vars['key_strings']); - unset($http_vars['switcher']); - $container = (isset($http_vars['container_id']) && $http_vars['container_id']) ? $http_vars['container_id'] : null; - $result = GetSimpleFormats($server, isset($http_vars['block_mode']), $container, $lang, $formatKeyStrings, $http_vars); - break; - - default: - $result = HandleSimpleDefault($http_vars); - break; - } - - return $result; - } - - /*******************************************************************/ - /** - \brief This returns the search results, in whatever form was requested. - - \returns XHTML data. It will either be a table, or block elements. - */ - function GetSimpleSearchResults( - $in_http_vars, ///< The HTTP GET and POST parameters. - $in_block = false, ///< If this is true, the results will be sent back as block elements (div tags), as opposed to a table. Default is false. - $in_container_id = null ///< This is an optional ID for the "wrapper." - ) { - $localized_strings = c_comdef_server::GetLocalStrings(); - $original_weekday = -1; - $current_weekday = -1; - - if (!( isset($in_http_vars['geo_width']) && $in_http_vars['geo_width'] ) && isset($in_http_vars['bmlt_search_type']) && ($in_http_vars['bmlt_search_type'] == 'advanced') && isset($in_http_vars['advanced_radius']) && isset($in_http_vars['advanced_mapmode']) && $in_http_vars['advanced_mapmode'] && ( floatval($in_http_vars['advanced_radius'] != 0.0) ) && isset($in_http_vars['lat_val']) && isset($in_http_vars['long_val']) && ( (floatval($in_http_vars['lat_val']) != 0.0) || (floatval($in_http_vars['long_val']) != 0.0) )) { - $in_http_vars['geo_width'] = $in_http_vars['advanced_radius']; - } elseif (!( isset($in_http_vars['geo_width']) && $in_http_vars['geo_width'] ) && isset($in_http_vars['bmlt_search_type']) && ($in_http_vars['bmlt_search_type'] == 'advanced')) { - $in_http_vars['lat_val'] = null; - $in_http_vars['long_val'] = null; - } elseif (!isset($in_http_vars['geo_loc']) || $in_http_vars['geo_loc'] != 'yes') { - if (!isset($in_http_vars['geo_width'])) { - $in_http_vars['geo_width'] = 0; - } - } - - if (!(isset($in_http_vars['sort_key']) && $in_http_vars['sort_key']) && !(isset($in_http_vars['sort_keys']) && $in_http_vars['sort_keys'])) { - $in_http_vars['sort_key'] = 'time'; - } - - require_once(dirname(__FILE__).'/../csv/search_results_csv.php'); - $results = DisplaySearchResultsCSV($in_http_vars); - - $ret = ''; - - // What we do, is to parse the CSV return. We'll pick out certain fields, and format these into a table or block element return. - if ($results) { - if (isset($in_http_vars['single_uri']) && $in_http_vars['single_uri']) { - $single_uri = $in_http_vars['single_uri']; - } - - // Start by turning the CSV into an array of meeting lines. - $results = explode("\n", $results); - - if (is_array($results) && count($results)) { - $ret = $in_block ? '
' : ''; - $keys = preg_replace('|^"|', '', preg_replace('|"$|', '', explode('","', $results[0]))); - $weekday_div = false; - - $alt = 1; // This is used to provide an alternating class. - // We skip the first line, because that is the field header. - for ($count = 1; $count < count($results); $count++) { - $meeting = $results[$count]; - - if ($meeting) { - if ($alt == 1) { - $alt = 0; - } else { - $alt = 1; - } - - $meeting = preg_replace('|^"|', '', preg_replace('|"$|', '', explode('","', $meeting))); - if (is_array($meeting) && count($meeting)) { - if (count($meeting) > count($keys)) { - $keys[] = 'unused'; - } - - // This is for convenience. We turn the meeting array into an associative one by adding the keys. - $meeting = array_combine($keys, $meeting); - $location_borough = c_comdef_htmlspecialchars(trim(stripslashes($meeting['location_city_subsection']))); - $location_neighborhood = c_comdef_htmlspecialchars(trim(stripslashes($meeting['location_neighborhood']))); - $location_province = c_comdef_htmlspecialchars(trim(stripslashes($meeting['location_province']))); - $location_nation = c_comdef_htmlspecialchars(trim(stripslashes($meeting['location_nation']))); - $location_postal_code_1 = c_comdef_htmlspecialchars(trim(stripslashes($meeting['location_postal_code_1']))); - $location_municipality = c_comdef_htmlspecialchars(trim(stripslashes($meeting['location_municipality']))); - $town = ''; - - if ($location_municipality) { - if ($location_borough) { - // We do it this verbose way, so we will scrag the comma if we want to hide the town. - $town = "$location_borough, $location_municipality"; - } else { - $town = "$location_municipality"; - } - } elseif ($location_borough) { - $town = "$location_borough"; - } - - if ($location_province) { - if ($town) { - $town .= ', '; - } - - $town .= "$location_province"; - } - - if ($location_postal_code_1) { - if ($town) { - $town .= ', '; - } - - $town .= "$location_postal_code_1"; - } - - if ($location_nation) { - if ($town) { - $town .= ', '; - } - - $town .= "$location_nation"; - } - - if ($location_neighborhood) { - $town_temp = ''; - - if ($town) { - $town_temp = ' ('; - } - - $town_temp .= "$location_neighborhood"; - - if ($town) { - $town_temp .= ')'; - } - - $town .= $town_temp; - } - - $weekday = c_comdef_htmlspecialchars($localized_strings['weekdays'][intval($meeting['weekday_tinyint'])]); - $time = BuildMeetingTime($meeting['start_time']); - - $address = ''; - $location_text = c_comdef_htmlspecialchars(trim(stripslashes($meeting['location_text']))); - $street = c_comdef_htmlspecialchars(trim(stripslashes($meeting['location_street']))); - $info = c_comdef_htmlspecialchars(trim(stripslashes($meeting['location_info']))); - - if ($location_text) { - $address = "$location_text"; - } - - if ($street) { - if ($address) { - $address .= ', '; - } - - $address .= "$street"; - } - - if ($info) { - if ($address) { - $address .= ' '; - } - - $address .= "($info)"; - } - - $name = c_comdef_htmlspecialchars(trim(stripslashes($meeting['meeting_name']))); - $format = c_comdef_htmlspecialchars(trim(stripslashes($meeting['formats']))); - - $name_uri = urlencode(htmlspecialchars_decode($name)); - - $map_uri = str_replace("##LONG##", c_comdef_htmlspecialchars($meeting['longitude']), str_replace("##LAT##", c_comdef_htmlspecialchars($meeting['latitude']), str_replace("##NAME##", $name_uri, $localized_strings['comdef_server_admin_strings']['MapsURL']))); - - if ($time && $weekday && $address) { - $meeting_weekday = $meeting['weekday_tinyint']; - - if (7 < $meeting_weekday) { - $meeting_weekday = 1; - } - - if (($current_weekday != $meeting_weekday) && $in_block) { - if ($current_weekday != -1) { - $weekday_div = false; - $ret .= ''; - } - - $current_weekday = $meeting_weekday; - - $ret .= '
'; - $weekday_div = true; - if (isset($in_http_vars['weekday_header']) && $in_http_vars['weekday_header']) { - $ret .= '
'.htmlspecialchars($weekday).'
'; - } - } - - $ret .= $in_block ? '
' : '
'; - $ret .= $in_block ? '
' : '
'; - $ret .= $in_block ? '
' : '
'; - - $ret .= $in_block ? '
' : '
'; - - $ret .= $in_block ? '
' : '
'; - - $ret .= $in_block ? '
' : '
'; - - $ret .= $in_block ? '
' : '
'; - - $ret .= $in_block ? '
' : ''; - } - } - } - } - - if ($weekday_div && $in_block) { - $ret .= ''; - } - - $ret .= $in_block ? '' : '
'; - $ret .= $town; - $ret .= $in_block ? '' : ''; - - if (isset($single_uri) && $single_uri) { - $ret .= ''; - } - - if ($name) { - $ret .= $name; - } else { - $ret .= $localized_strings['comdef_server_admin_strings']['Value_Prompts']['generic']; - } - - if (isset($single_uri) && $single_uri) { - $ret .= ''; - } - - $ret .= $in_block ? '' : ''; - $ret .= $time; - $ret .= $in_block ? '' : ''; - $ret .= $weekday; - $ret .= $in_block ? '' : ''; - $ret .= ''.$address.''; - $ret .= $in_block ? '' : ''; - $ret .= $format; - $ret .= $in_block ? '' : '
'; - } - } - - return $ret; - } - - /*******************************************************************/ - /** \brief This creates a time string to be displayed for the meeting. - The display is done in non-military time, and "midnight" and - "noon" are substituted for 12:59:00, 00:00:00 and 12:00:00 - - \returns a string, containing the HTML rendered by the function. - */ - function BuildMeetingTime( - $in_time ///< A string. The value of the time field. - ) { - $localized_strings = c_comdef_server::GetLocalStrings(); - - $time = null; - - if (($in_time == "00:00:00") || ($in_time >= "23:55:00")) { - $time = c_comdef_htmlspecialchars($localized_strings['comdef_server_admin_strings']['meeting_editor_screen_meeting_midnight_label']); - } elseif ($in_time == "12:00:00") { - $time = c_comdef_htmlspecialchars($localized_strings['comdef_server_admin_strings']['meeting_editor_screen_meeting_noon_label']); - } else { - include(dirname(__FILE__).'/../../server/config/get-config.php'); - - $time = c_comdef_htmlspecialchars(date($time_format, strtotime($in_time))); - } - - return $time; - } - - /*******************************************************************/ - /** - \brief This returns the complete formats table. - - \returns XHTML data, with the first row a key header. - */ - function GetSimpleFormats( - &$server, ///< A reference to an instance of c_comdef_server - $in_block = false, ///< If this is true, the results will be sent back as block elements (div tags), as opposed to a table. Default is false. - $in_container_id = null, ///< This is an optional ID for the "wrapper." - $in_lang = null, ///< The language of the formats to be returned. Default is null (server language). Can be an array. - $in_key_strings = null, ///< If supplied, an array of format key strings to be returned. - $in_search_params = null ///< If this is supplied, then it is a search parameter list. The idea is that only the formats used in the returned meetings will be displayed. - ) { - $my_keys = array ( 'key_string', - 'name_string', - 'description_string' - ); - - $ret = $in_block ? '
' : ''; - $formats_ar = array(); - - if (isset($in_search_params) && is_array($in_search_params) && count($in_search_params)) { - require_once(dirname(__FILE__).'/../csv/search_results_csv.php'); - $results = GetSearchResults($in_search_params, $formats_ar); - } - - $formats_obj = $server->GetFormatsObj(); - if ($formats_obj instanceof c_comdef_formats) { - $langs = $server->GetServerLangs(); - - if (is_array($in_lang) && count($in_lang)) { - $langs2 = array(); - foreach ($in_lang as $key) { - if (array_key_exists($key, $langs)) { - $langs2[$key] = $langs[$key]; - } - } - - $langs = $langs2; - } elseif (array_key_exists($in_lang, $langs)) { - $langs = array ( $in_lang => $langs[$in_lang] ); - } - - foreach ($langs as $key => $value) { - $format_array = $formats_obj->GetFormatsByLanguage($key); - - if (is_array($format_array) && count($format_array)) { - usort($format_array, function ($a, $b) { - return strnatcasecmp($a->GetKey(), $b->GetKey()); - }); - - $alt = 1; // This is used to provide an alternating style. - foreach ($format_array as $format) { - $has = false; - - if (isset($in_key_strings) && is_array($in_key_strings) && count($in_key_strings)) { - if (!in_array($format->GetKey(), $in_key_strings)) { - continue; - } - } - - if ($format instanceof c_comdef_format) { - if (($formats_ar != null)) { - foreach ($formats_ar as $format_obj) { - if ($format->GetSharedID() && ($format_obj->GetSharedID() == $format->GetSharedID())) { - $has = true; - break; - } - } - } - - if ($has) { - if ($alt == 1) { - $alt = 0; - } else { - $alt = 1; - } - - $ret .= $in_block ? '
' : '
'; - foreach ($my_keys as $ky) { - $ret .= ($in_block ? '' : '_td">'; - $ret .= c_comdef_htmlspecialchars(trim($val)); - $ret .= $in_block ? '' : ''; - } - $ret .= $in_block ? '
' : '
'; - } - } - } - } - } - } - - $ret .= $in_block ? '' : '
'; - - return $ret; - } - - /*******************************************************************/ - /** - \brief Handles no command supplied (error) - - \returns English error string (not XML). - */ - function HandleSimpleDefault( - $in_http_vars ///< The HTTP GET and POST parameters. - ) { - return "You must supply either 'switcher=GetSearchResults' or 'switcher=GetFormats'"; - } - - $ret = parse_redirect_simple($server); -} else { - $ret = HandleNoServer(); -} - -$handler = 'ob_gzhandler'; - -// Server-side includes (and some other implementations) can't handle compressed data in the response. If "nocompress" is specified, then the GZIP handler isn't used. -if (isset($_GET['nocompress']) || isset($_POST['nocompress'])) { - $handler = null; -} - -ob_start($handler); - $ret = preg_replace('//', '', $ret); - $ret = preg_replace('/\/\*(.|\s)*?\*\//', '', $ret); - $ret = preg_replace("|\s+\/\/.*|", " ", $ret); - $ret = preg_replace("/\s+/", " ", $ret); - echo $ret; -ob_end_flush(); diff --git a/src/legacy/client_interface/xml/GetLangs.php b/src/legacy/client_interface/xml/GetLangs.php deleted file mode 100755 index a36c63da6..000000000 --- a/src/legacy/client_interface/xml/GetLangs.php +++ /dev/null @@ -1,68 +0,0 @@ -. -********************************************************************************************/ - -defined('BMLT_EXEC') or define('BMLT_EXEC', true); // This is a security verifier. Keeps files from being executed outside of the context -$file_dir = str_replace('/client_interface/xml', '', dirname(__FILE__)).'/server/c_comdef_server.class.php'; -require_once($file_dir); -$server = c_comdef_server::MakeServer(); -$ret = null; - -if ($server instanceof c_comdef_server) { - $langs = $server->GetServerLangs(); - - if ($langs) { - // The caller can request compression. Not all clients can deal with compressed replies. - if (isset($_GET['compress_xml']) || isset($_POST['compress_xml'])) { - ob_start('ob_gzhandler'); - } else { - header('Content-Type:application/xml; charset=UTF-8'); - ob_start(); - } - echo '<'.'?'.'xml version="1.0" encoding="UTF-8"'.'?'.'>'; - - $port = $_SERVER['SERVER_PORT'] ; - // IIS puts "off" in the HTTPS field, so we need to test for that. - $https = (!empty($_SERVER['HTTPS']) && (($_SERVER['HTTPS'] !== 'off') || ($port == 443))); - $server_path = $_SERVER['SERVER_NAME']; - $my_path = dirname(dirname($_SERVER['SCRIPT_NAME'])).'/xsd/GetLangs.php'; - $server_path .= trim((($https && ($port != 443)) || (!$https && ($port != 80))) ? ':'.$port : '', '/'); - $xsd_uri = 'http'.($https ? 's' : '').'://'.$server_path.$my_path; - - echo ""; - - foreach ($langs as $key_string => $name_string) { - echo 'GetLocalLang())) { - echo ' default="1"'; - } - echo '>'; - echo htmlspecialchars($name_string); - echo ''; - } - - echo ""; - ob_end_flush(); - } else { - echo ( 'No Languages' ); - } -} else { - echo ( 'No Server' ); -} diff --git a/src/legacy/client_interface/xml/GetServiceBodies.php b/src/legacy/client_interface/xml/GetServiceBodies.php deleted file mode 100755 index 34323a019..000000000 --- a/src/legacy/client_interface/xml/GetServiceBodies.php +++ /dev/null @@ -1,31 +0,0 @@ -/client_interface/json/ - with the same parameters that you would send to an advanced search. The results - will be returned as an XML file. - - This file can be called from other servers. - - This file is part of the Basic Meeting List Toolbox (BMLT). - - Find out more at: https://bmlt.app - - BMLT is free software: you can redistribute it and/or modify - it under the terms of the MIT License. - - BMLT is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - MIT License for more details. - - You should have received a copy of the MIT License along with this code. - If not, see . -*/ - -defined('BMLT_EXEC') or define('BMLT_EXEC', true); // This is a security verifier. Keeps files from being executed outside of the context -$_GET['switcher'] = 'GetServiceBodies'; -require_once(dirname(__FILE__).'/index.php'); diff --git a/src/legacy/client_interface/xml/index.php b/src/legacy/client_interface/xml/index.php deleted file mode 100755 index e83934659..000000000 --- a/src/legacy/client_interface/xml/index.php +++ /dev/null @@ -1,59 +0,0 @@ -/client_interface/xml/ - with the same parameters that you would send to an advanced search. The results - will be returned as an XML file. - - This file can be called from other servers. - - This file is part of the Basic Meeting List Toolbox (BMLT). - - Find out more at: https://bmlt.app - - BMLT is free software: you can redistribute it and/or modify - it under the terms of the MIT License. - - BMLT is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - MIT License for more details. - - You should have received a copy of the MIT License along with this code. - If not, see . -*/ - -defined('BMLT_EXEC') or define('BMLT_EXEC', true); // This is a security verifier. Keeps files from being executed outside of the context -require_once(dirname(__FILE__).'/../csv/csv.php'); - -try { - $server = c_comdef_server::MakeServer(); - $ret = null; - - if ($server instanceof c_comdef_server) { - $_GET['xml_data'] = true; - $ret = parse_redirect($server); - // The caller can request compression. Not all clients can deal with compressed replies. - if (isset($_GET['compress_output']) || isset($_POST['compress_output'])) { - if (zlib_get_coding_type() === false) { - ob_start("ob_gzhandler"); - } else { - header('Content-Type:application/xml; charset=UTF-8'); - ob_start(); - } - } else { - header('Content-Type:application/xml; charset=UTF-8'); - ob_start(); - } - - echo $ret; - ob_end_flush(); - } else { - echo HandleNoServer(); - } -} catch (Exception $e) { - echo HandleNoServer(); -} diff --git a/src/legacy/client_interface/xsd/AdminPermissions.php b/src/legacy/client_interface/xsd/AdminPermissions.php deleted file mode 100644 index e53371ab6..000000000 --- a/src/legacy/client_interface/xsd/AdminPermissions.php +++ /dev/null @@ -1,52 +0,0 @@ -. -********************************************************************************************/ - -// The caller can request compression. Not all clients can deal with compressed replies. -if (isset($_GET['compress_xml']) || isset($_POST['compress_xml'])) { - if (zlib_get_coding_type() === false) { - ob_start("ob_gzhandler"); - } else { - header('Content-Type:application/xml; charset=UTF-8'); - ob_start(); - } -} else { - header('Content-Type:application/xml; charset=UTF-8'); - ob_start(); -} -echo "<"."?xml version=\"1.0\" encoding=\"UTF-8\"?".">\n"; ?> - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/legacy/client_interface/xsd/ChangeResponse.php b/src/legacy/client_interface/xsd/ChangeResponse.php deleted file mode 100755 index c19a9bc8c..000000000 --- a/src/legacy/client_interface/xsd/ChangeResponse.php +++ /dev/null @@ -1,75 +0,0 @@ -. -********************************************************************************************/ - -// The caller can request compression. Not all clients can deal with compressed replies. -if (isset($_GET['compress_xml']) || isset($_POST['compress_xml'])) { - if (zlib_get_coding_type() === false) { - ob_start("ob_gzhandler"); - } else { - header('Content-Type:application/xml; charset=UTF-8'); - ob_start(); - } -} else { - header('Content-Type:application/xml; charset=UTF-8'); - ob_start(); -} -echo "<"."?xml version=\"1.0\" encoding=\"UTF-8\"?".">\n"; ?> -' elementFormDefault='qualified' targetNamespace='http://'> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/legacy/client_interface/xsd/DeletedMeeting.php b/src/legacy/client_interface/xsd/DeletedMeeting.php deleted file mode 100755 index 07d01e833..000000000 --- a/src/legacy/client_interface/xsd/DeletedMeeting.php +++ /dev/null @@ -1,53 +0,0 @@ -. -********************************************************************************************/ - -// The caller can request compression. Not all clients can deal with compressed replies. -if (isset($_GET['compress_xml']) || isset($_POST['compress_xml'])) { - if (zlib_get_coding_type() === false) { - ob_start("ob_gzhandler"); - } else { - header('Content-Type:application/xml; charset=UTF-8'); - ob_start(); - } -} else { - header('Content-Type:application/xml; charset=UTF-8'); - ob_start(); -} -echo "<"."?xml version=\"1.0\" encoding=\"UTF-8\"?".">\n"; ?> - - - - - - - - - - - - - - - - diff --git a/src/legacy/client_interface/xsd/FieldTemplates.php b/src/legacy/client_interface/xsd/FieldTemplates.php deleted file mode 100755 index 5c8680560..000000000 --- a/src/legacy/client_interface/xsd/FieldTemplates.php +++ /dev/null @@ -1,63 +0,0 @@ -. -********************************************************************************************/ - -// The caller can request compression. Not all clients can deal with compressed replies. -if (isset($_GET['compress_xml']) || isset($_POST['compress_xml'])) { - if (zlib_get_coding_type() === false) { - ob_start("ob_gzhandler"); - } else { - header('Content-Type:application/xml; charset=UTF-8'); - ob_start(); - } -} else { - header('Content-Type:application/xml; charset=UTF-8'); - ob_start(); -} -echo "\n"; ?> - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/legacy/client_interface/xsd/GetChanges.php b/src/legacy/client_interface/xsd/GetChanges.php deleted file mode 100755 index b22c124fd..000000000 --- a/src/legacy/client_interface/xsd/GetChanges.php +++ /dev/null @@ -1,73 +0,0 @@ -. -********************************************************************************************/ - -// The caller can request compression. Not all clients can deal with compressed replies. -if (isset($_GET['compress_xml']) || isset($_POST['compress_xml'])) { - if (zlib_get_coding_type() === false) { - ob_start("ob_gzhandler"); - } else { - header('Content-Type:application/xml; charset=UTF-8'); - ob_start(); - } -} else { - header('Content-Type:application/xml; charset=UTF-8'); - ob_start(); -} -echo "<"."?xml version=\"1.0\" encoding=\"UTF-8\"?".">\n"; ?> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/legacy/client_interface/xsd/GetCoverageArea.php b/src/legacy/client_interface/xsd/GetCoverageArea.php deleted file mode 100755 index caee5a752..000000000 --- a/src/legacy/client_interface/xsd/GetCoverageArea.php +++ /dev/null @@ -1,57 +0,0 @@ -. -********************************************************************************************/ - -// The caller can request compression. Not all clients can deal with compressed replies. -if (isset($_GET['compress_xml']) || isset($_POST['compress_xml'])) { - if (zlib_get_coding_type() === false) { - ob_start("ob_gzhandler"); - } else { - header('Content-Type:application/xml; charset=UTF-8'); - ob_start(); - } -} else { - header('Content-Type:application/xml; charset=UTF-8'); - ob_start(); -} -echo "\n"; ?> - - - - - - - - - - - - - - - - - - - - diff --git a/src/legacy/client_interface/xsd/GetDeletedMeetings.php b/src/legacy/client_interface/xsd/GetDeletedMeetings.php deleted file mode 100755 index 2d1ec419a..000000000 --- a/src/legacy/client_interface/xsd/GetDeletedMeetings.php +++ /dev/null @@ -1,68 +0,0 @@ -. -********************************************************************************************/ - -// The caller can request compression. Not all clients can deal with compressed replies. -if (isset($_GET['compress_xml']) || isset($_POST['compress_xml'])) { - if (zlib_get_coding_type() === false) { - ob_start("ob_gzhandler"); - } else { - header('Content-Type:application/xml; charset=UTF-8'); - ob_start(); - } -} else { - header('Content-Type:application/xml; charset=UTF-8'); - ob_start(); -} -echo "<"."?xml version=\"1.0\" encoding=\"UTF-8\"?".">\n"; ?> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/legacy/client_interface/xsd/GetFieldKeys.php b/src/legacy/client_interface/xsd/GetFieldKeys.php deleted file mode 100755 index 94b37445f..000000000 --- a/src/legacy/client_interface/xsd/GetFieldKeys.php +++ /dev/null @@ -1,55 +0,0 @@ -. -********************************************************************************************/ - -// The caller can request compression. Not all clients can deal with compressed replies. -if (isset($_GET['compress_xml']) || isset($_POST['compress_xml'])) { - if (zlib_get_coding_type() === false) { - ob_start("ob_gzhandler"); - } else { - header('Content-Type:application/xml; charset=UTF-8'); - ob_start(); - } -} else { - header('Content-Type:application/xml; charset=UTF-8'); - ob_start(); -} -echo "\n"; ?> - - - - - - - - - - - - - - - - - - diff --git a/src/legacy/client_interface/xsd/GetFieldValues.php b/src/legacy/client_interface/xsd/GetFieldValues.php deleted file mode 100755 index adc1c518d..000000000 --- a/src/legacy/client_interface/xsd/GetFieldValues.php +++ /dev/null @@ -1,55 +0,0 @@ -. -********************************************************************************************/ - -// The caller can request compression. Not all clients can deal with compressed replies. -if (isset($_GET['compress_xml']) || isset($_POST['compress_xml'])) { - if (zlib_get_coding_type() === false) { - ob_start("ob_gzhandler"); - } else { - header('Content-Type:application/xml; charset=UTF-8'); - ob_start(); - } -} else { - header('Content-Type:application/xml; charset=UTF-8'); - ob_start(); -} -echo "\n"; ?> - - - - - - - - - - - - - - - - - - diff --git a/src/legacy/client_interface/xsd/GetFormats.php b/src/legacy/client_interface/xsd/GetFormats.php deleted file mode 100755 index 3ee303472..000000000 --- a/src/legacy/client_interface/xsd/GetFormats.php +++ /dev/null @@ -1,62 +0,0 @@ -. -********************************************************************************************/ - -// The caller can request compression. Not all clients can deal with compressed replies. -if (isset($_GET['compress_xml']) || isset($_POST['compress_xml'])) { - if (zlib_get_coding_type() === false) { - ob_start("ob_gzhandler"); - } else { - header('Content-Type:application/xml; charset=UTF-8'); - ob_start(); - } -} else { - header('Content-Type:application/xml; charset=UTF-8'); - ob_start(); -} -echo "\n"; ?> - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/legacy/client_interface/xsd/GetLangs.php b/src/legacy/client_interface/xsd/GetLangs.php deleted file mode 100755 index 6a371575e..000000000 --- a/src/legacy/client_interface/xsd/GetLangs.php +++ /dev/null @@ -1,55 +0,0 @@ -. -********************************************************************************************/ - -// The caller can request compression. Not all clients can deal with compressed replies. -if (isset($_GET['compress_xml']) || isset($_POST['compress_xml'])) { - if (zlib_get_coding_type() === false) { - ob_start("ob_gzhandler"); - } else { - header('Content-Type:application/xml; charset=UTF-8'); - ob_start(); - } -} else { - header('Content-Type:application/xml; charset=UTF-8'); - ob_start(); -} -echo "<"."?xml version=\"1.0\" encoding=\"UTF-8\"?".">\n"; ?> - - - - - - - - - - - - - - - - - - diff --git a/src/legacy/client_interface/xsd/GetMeetingLocationInfo.php b/src/legacy/client_interface/xsd/GetMeetingLocationInfo.php deleted file mode 100755 index 6d05f8667..000000000 --- a/src/legacy/client_interface/xsd/GetMeetingLocationInfo.php +++ /dev/null @@ -1,84 +0,0 @@ -. -********************************************************************************************/ - -// The caller can request compression. Not all clients can deal with compressed replies. -if (isset($_GET['compress_xml']) || isset($_POST['compress_xml'])) { - if (zlib_get_coding_type() === false) { - ob_start("ob_gzhandler"); - } else { - header('Content-Type:application/xml; charset=UTF-8'); - ob_start(); - } -} else { - header('Content-Type:application/xml; charset=UTF-8'); - ob_start(); -} -echo "\n"; ?> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/legacy/client_interface/xsd/GetSearchResults.php b/src/legacy/client_interface/xsd/GetSearchResults.php deleted file mode 100755 index 628aa6976..000000000 --- a/src/legacy/client_interface/xsd/GetSearchResults.php +++ /dev/null @@ -1,160 +0,0 @@ -. -********************************************************************************************/ - -defined('BMLT_EXEC') or define('BMLT_EXEC', true); // This is a security verifier. Keeps files from being executed outside of the context -$file_dir = str_replace('/client_interface/xsd', '', dirname(__FILE__)).'/server/c_comdef_server.class.php'; -require_once($file_dir); -$server = c_comdef_server::MakeServer(); -$ret = null; - -if ($server instanceof c_comdef_server) { - // The caller can request compression. Not all clients can deal with compressed replies. - if (isset($_GET['compress_xml']) || isset($_POST['compress_xml'])) { - if (zlib_get_coding_type() === false) { - ob_start("ob_gzhandler"); - } else { - header('Content-Type:application/xml; charset=UTF-8'); - ob_start(); - } - } else { - header('Content-Type:application/xml; charset=UTF-8'); - ob_start(); - } - echo "\n"; ?> - - - - - - - - \n"; - } - ?> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/legacy/client_interface/xsd/GetServiceBodies.php b/src/legacy/client_interface/xsd/GetServiceBodies.php deleted file mode 100755 index db2a5197c..000000000 --- a/src/legacy/client_interface/xsd/GetServiceBodies.php +++ /dev/null @@ -1,62 +0,0 @@ -. -********************************************************************************************/ - -// The caller can request compression. Not all clients can deal with compressed replies. -if (isset($_GET['compress_xml']) || isset($_POST['compress_xml'])) { - if (zlib_get_coding_type() === false) { - ob_start("ob_gzhandler"); - } else { - header('Content-Type:application/xml; charset=UTF-8'); - ob_start(); - } -} else { - header('Content-Type:application/xml; charset=UTF-8'); - ob_start(); -} -echo "\n"; ?> - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/legacy/client_interface/xsd/HierServiceBodies.php b/src/legacy/client_interface/xsd/HierServiceBodies.php deleted file mode 100644 index 5e187707f..000000000 --- a/src/legacy/client_interface/xsd/HierServiceBodies.php +++ /dev/null @@ -1,146 +0,0 @@ -. -********************************************************************************************/ - -// The caller can request compression. Not all clients can deal with compressed replies. -if (isset($_GET['compress_xml']) || isset($_POST['compress_xml'])) { - if (zlib_get_coding_type() === false) { - ob_start("ob_gzhandler"); - } else { - header('Content-Type:application/xml; charset=UTF-8'); - ob_start(); - } -} else { - header('Content-Type:application/xml; charset=UTF-8'); - ob_start(); -} -echo "<"."?xml version=\"1.0\" encoding=\"UTF-8\"?".">\n"; ?> -' elementFormDefault='qualified' targetNamespace='http://'> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/legacy/client_interface/xsd/RestoreDeletedMeeting.php b/src/legacy/client_interface/xsd/RestoreDeletedMeeting.php deleted file mode 100755 index 6da4d5fef..000000000 --- a/src/legacy/client_interface/xsd/RestoreDeletedMeeting.php +++ /dev/null @@ -1,61 +0,0 @@ -. -********************************************************************************************/ - -// The caller can request compression. Not all clients can deal with compressed replies. -if (isset($_GET['compress_xml']) || isset($_POST['compress_xml'])) { - if (zlib_get_coding_type() === false) { - ob_start("ob_gzhandler"); - } else { - header('Content-Type:application/xml; charset=UTF-8'); - ob_start(); - } -} else { - header('Content-Type:application/xml; charset=UTF-8'); - ob_start(); -} -echo "<"."?xml version=\"1.0\" encoding=\"UTF-8\"?".">\n"; ?> - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/legacy/client_interface/xsd/ServerInfo.php b/src/legacy/client_interface/xsd/ServerInfo.php deleted file mode 100755 index f55903517..000000000 --- a/src/legacy/client_interface/xsd/ServerInfo.php +++ /dev/null @@ -1,74 +0,0 @@ -. -********************************************************************************************/ - -// The caller can request compression. Not all clients can deal with compressed replies. -if (isset($_GET['compress_xml']) || isset($_POST['compress_xml'])) { - if (zlib_get_coding_type() === false) { - ob_start("ob_gzhandler"); - } else { - header('Content-Type:application/xml; charset=UTF-8'); - ob_start(); - } -} else { - header('Content-Type:application/xml; charset=UTF-8'); - ob_start(); -} -echo "<"."?xml version=\"1.0\" encoding=\"UTF-8\"?".">\n"; ?> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/legacy/client_interface/xsd/UserInfo.php b/src/legacy/client_interface/xsd/UserInfo.php deleted file mode 100644 index 5e45b5509..000000000 --- a/src/legacy/client_interface/xsd/UserInfo.php +++ /dev/null @@ -1,52 +0,0 @@ -. -********************************************************************************************/ - -// The caller can request compression. Not all clients can deal with compressed replies. -if (isset($_GET['compress_xml']) || isset($_POST['compress_xml'])) { - if (zlib_get_coding_type() === false) { - ob_start("ob_gzhandler"); - } else { - header('Content-Type:application/xml; charset=UTF-8'); - ob_start(); - } -} else { - header('Content-Type:application/xml; charset=UTF-8'); - ob_start(); -} -echo "<"."?xml version=\"1.0\" encoding=\"UTF-8\"?".">\n"; ?> - - - - - - - - - - - - - - - diff --git a/src/legacy/client_interface/xsd/index.htm b/src/legacy/client_interface/xsd/index.htm deleted file mode 100755 index e69de29bb..000000000 diff --git a/src/legacy/index.php b/src/legacy/index.php deleted file mode 100755 index 88450484e..000000000 --- a/src/legacy/index.php +++ /dev/null @@ -1,22 +0,0 @@ -. -*/ -ob_start(); -define('__DEBUG_MODE__', 1); // Uncomment to make the CSS and JavaScript easier to trace (and less efficient). -defined('BMLT_EXEC') or define('BMLT_EXEC', 1); -include(dirname(__FILE__).'/local_server/index.php'); -ob_end_flush(); diff --git a/src/legacy/local_server/bmlt.js b/src/legacy/local_server/bmlt.js deleted file mode 100644 index 20c91c7f6..000000000 --- a/src/legacy/local_server/bmlt.js +++ /dev/null @@ -1,122 +0,0 @@ -var bmltbaseURL; -var recurseServiceBodies; - -var bmltClientInit = function (host, recurse) { - this.bmltbaseURL = host + "/client_interface/jsonp/?switcher="; - this.recurseServiceBodies = recurse == null ? false : recurse; -}; - -var getDayOfWeek = function (dayint) { - return ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"][dayint]; -}; - -var getTodayDayOfWeek = function () { - return (new Date()).getDay() + 1; -}; - -var militaryToStandard = function (value) { - if (value !== null && value !== undefined) { //If value is passed in - if (value.indexOf('AM') > -1 || value.indexOf('PM') > -1) { //If time is already in standard time then don't format. - return value; - } else { - if (value.length === 8) { //If value is the expected length for military time then process to standard time. - var valueconv = value.split(':'); // convert to array - // fetch - var hours = Number(valueconv[0]); - - // calculate - var timeValue; - if (hours > 0 && hours <= 12) { // If hour is less than or equal to 12 then convert to standard 12 hour format - timeValue= "" + hours; - } else if (hours > 12) { //If hour is greater than 12 then convert to standard 12 hour format - timeValue= "" + (hours - 12); - } else if (hours === 0) { //If hour is 0 then set to 12 for standard time 12 AM - timeValue= "12"; - } - - timeValue += ":" + valueconv[1]; // get minutes - timeValue += (hours >= 12) ? " PM" : " AM"; // get AM/PM - // show - return timeValue; - } else { //If value is not the expected length than just return the value as is - return valueconv; - } - } - } -}; - -var getMeetingsByCity = function (city, callback) { - getJSON(bmltbaseURL + "GetSearchResults&meeting_key=location_municipality&meeting_key_value=" + city + "&callback=?", callback); -}; - -var getMeetingsByServiceBodyId = function (serviceBodyId, callback) { - getJSON(bmltbaseURL + "GetSearchResults" + getServiceBodyIdQueryString(serviceBodyId) + "&callback=?", callback); -}; - -var getMeetingsByServiceBodyIdAndWeekdayId = function (serviceBodyId, weekdayId, callback) { - getJSON(bmltbaseURL + "GetSearchResults" + getServiceBodyIdQueryString(serviceBodyId) + "&weekdays=" + weekdayId + "&callback=?", callback); -}; - -var getMeetingsByServiceBodyIdAndCity = function (serviceBodyId, city, callback) { - getJSON(bmltbaseURL + "GetSearchResults" + getServiceBodyIdQueryString(serviceBodyId) + "&meeting_key=location_municipality&meeting_key_value=" + city + "&callback=?", callback); -}; - -var getMeetingsByLocation = function (day, geoWidth, position, callback) { - getJSON(bmltbaseURL + "GetSearchResults&weekdays=" + day + "&geo_width=" + geoWidth + "&long_val=" + position.longitude + "&lat_val=" + position.latitude + "&callback=?", callback); -}; - -var getFormats = function (callback) { - getJSON(bmltbaseURL + "GetFormats&callback=?", callback); -}; - -var getUniqueValuesByServiceBody = function (serviceBodyId, field, callback) { - getMeetingsByServiceBodyId(serviceBodyId, function (data) { - var valuesArray = []; - for (i = 0; i < data.length; i++) { - valuesArray.push(data[i][field]); - } - - callback(valuesArray.unique()) - }); -}; - -var getServiceBodyIdQueryString = function (serviceBodyIds) { - var serviceBodyIdString = ""; - if (Array.isArray(serviceBodyIds)) { - for (var i = 0; i < serviceBodyIds.length; i++) { - serviceBodyIdString += "&services[]=" + serviceBodyIds[i]; - } - } else { - serviceBodyIdString = "&services=" + serviceBodyIds; - } - - return serviceBodyIdString; -}; - -var getJSON = function (url, callback) { - var random = Math.floor(Math.random() * 999999); - var callbackFunctionName = "cb_" + random; - if (this.recurseServiceBodies) { - url += "&recursive=1"; - } - url = url.replace("callback=?", "callback=" + callbackFunctionName); - - window[callbackFunctionName] = function (data) { - callback(data); - }; - - var scriptItem = document.createElement('script'); - scriptItem.setAttribute('src', url); - document.body.appendChild(scriptItem); -}; - -Array.prototype.unique = function () { - var o = {}, a = []; - for (var i = 0; i < this.length; i++) { - o[this[i]] = 1 - for (var e in o) { - a.push(e) - return a - } - } -}; diff --git a/src/legacy/local_server/db_connect.php b/src/legacy/local_server/db_connect.php deleted file mode 100644 index 2cbf26f52..000000000 --- a/src/legacy/local_server/db_connect.php +++ /dev/null @@ -1,42 +0,0 @@ -. -*/ -/** - \brief This function checks to make sure the database is correct for the current version. -*/ -function DB_Connect_and_Upgrade() -{ - global $dbPrefix; - - include(dirname(__FILE__)."/../server/config/get-config.php"); - - if (!isset($dbType)) { - $dbType = 'mysql'; - } - - if (!isset($dbServer)) { - $dbServer = 'localhost'; - } - - if (!isset($dbPrefix)) { - $dbPrefix = 'na'; - } - - c_comdef_dbsingleton::init($dbType, $dbServer, $dbName, $dbUser, $dbPassword, 'utf8'); - - // Migration code that used to be here was moved to a laravel migration -} diff --git a/src/legacy/local_server/index.php b/src/legacy/local_server/index.php deleted file mode 100755 index 791a9ae8b..000000000 --- a/src/legacy/local_server/index.php +++ /dev/null @@ -1,102 +0,0 @@ -. -*/ -defined('BMLT_EXEC') or die('Cannot Execute Directly'); // Makes sure that this file is in the correct context. -define('_LANG_COOKIE_NAME', 'bmlt_admin_lang_pref'); - -global $http_vars; -$http_vars = array_merge($_GET, $_POST); -$lang_enum = ''; - -// We use a cookie to store the language pref. -$lang_enum = request()->cookie(_LANG_COOKIE_NAME, $lang_enum); - -if (isset($http_vars['lang_enum']) && $http_vars['lang_enum']) { - $lang_enum = $http_vars['lang_enum']; -} - -$http_vars['lang_enum'] = $lang_enum; // Quick and dirty way to ensure that this gets properly propagated. - -$file_loc = dirname(__FILE__).'/install_wizard/index.php'; - -require_once($file_loc); // We test for the install wizard, first. - -if (isset($g_enable_language_selector) && $g_enable_language_selector) { - cookie()->queue(_LANG_COOKIE_NAME, $lang_enum, 60 * 24 * 365); -} - -if (isset($http_vars ['bmlt_ajax_callback'])) { - require_once(dirname(__FILE__).'/server_admin/c_comdef_admin_ajax_handler.class.php'); -} else { - ?> - - - - - - - - - - - - Basic Meeting List Toolbox Administration Console - - - GetCurrentUserObj(); - if (($user_obj instanceof c_comdef_user) && ($user_obj->GetUserLevel() != _USER_LEVEL_DEACTIVATED)) { - echo '
'; - // OK. If they make it in here, it means they are legit, so display the logged-in console. - require_once(dirname(__FILE__).'/server_admin/main_console.php'); - echo '
'; - } - } else { - ?> -

ERROR: NO SERVER!

- - - - diff --git a/src/legacy/local_server/install_wizard/auto-config.inc.php.example.txt b/src/legacy/local_server/install_wizard/auto-config.inc.php.example.txt deleted file mode 100644 index 6ee5106b6..000000000 --- a/src/legacy/local_server/install_wizard/auto-config.inc.php.example.txt +++ /dev/null @@ -1,51 +0,0 @@ -'; // This is the name of the database. - $dbUser = ''; // This is the SQL user that is authorized for the above database. - $dbPassword = ''; // This is the password for the above authorized user. Make it a big, ugly hairy one. It is powerful, and there is no need to remember it. - $dbServer = 'localhost'; // This is the host/server for accessing the database. - $dbPrefix = 'na'; // This is a table name prefix that can be used to differentiate tables used by different root server instances that share the same database. - - // Location and Map settings: - $region_bias = 'us'; // This is a 2-letter code for a 'region bias,' which helps Google Maps to figure out ambiguous search queries. - $gkey = ''; // This is the Google Maps JavaScript API Key, necessary for using Google Maps. - $search_spec_map_center = array ( 'longitude' => -118.563659, 'latitude' => 34.235918, 'zoom' => 6 ); // This is the default map location for new meetings. - $comdef_distance_units = 'mi'; - - // Display settings: - $bmlt_title = 'Basic Meeting List Toolbox Administration'; // This is the page title and heading for the main administration login page. - $banner_text = 'Administration Login'; // This is text that is displayed just above the login box on the main login page. - - // Miscellaneous settings: - $comdef_global_language ='en'; // This is the 2-letter code for the default root server localization (will default to 'en' -English, if the localization is not available). - $min_pw_len = 10; // The minimum number of characters in a user account password for this root server. - $number_of_meetings_for_auto = 10; // This is an approximation of the number of meetings to search for in the auto-search feature. The higher the number, the wider the radius. - $change_depth_for_meetings = 5; // This is how many changes should be recorded for each meeting. - // The higher the number, the larger the database will grow, as this can become quite substantial. - $default_duration_time = '1:30:00'; // This is the default duration for meetings that have no duration specified. - $g_enable_language_selector = FALSE; // Set this to TRUE (or 1) to enable a popup on the login screen that allows the administrator to select their language. - $g_enable_semantic_admin = FALSE; // If this is TRUE (or 1), then Semantic Administration for this Server is enabled (Administrators can log in using apps). - $g_defaultClosedStatus = TRUE; // If this is FALSE (or 0), then the default (unspecified) Open/Closed format for meetings reported to NAWS is OPEN. Otherwise, it is CLOSED. - - // These reflect the way that we handle contact emails. - $g_enable_email_contact = FALSE; // If this is TRUE (or 1), then this will enable the ability to contact meeting list contacts via a secure email form. - $include_service_body_admin_on_emails = FALSE; // If this is TRUE (or 1), then any emails sent using the meeting contact will include the nearest Service Body Admin - // contact for the meeting Service body (ignored, if $g_enable_email_contact is FALSE). - $include_every_admin_on_emails = FALSE; // If this is TRUE (or 1), then any emails sent using the meeting contact will include all Service Body Admin contacts - // (including the Server Administrator) for the meeting. - // (ignored, if $g_enable_email_contact or $include_service_body_admin_on_emails is FALSE) - - // Add any languages for which formats will be given - // The server languages are supported by default, the langs specified here add to them - // $format_lang_names = ['fa'=>'Farsi']; - // These are 'hard-coded,' but can be changed later. - - $time_format = 'g:i A'; // The PHP date() format for the times displayed. - $change_date_format = 'g:i A, n/j/Y'; // The PHP date() format for times/dates displayed in the change records. - $admin_session_name = 'BMLT_Admin'; // This is merely the 'tag' used to identify the BMLT admin session. -?> \ No newline at end of file diff --git a/src/legacy/local_server/install_wizard/country_names_and_code_elements.txt b/src/legacy/local_server/install_wizard/country_names_and_code_elements.txt deleted file mode 100644 index 13984676d..000000000 --- a/src/legacy/local_server/install_wizard/country_names_and_code_elements.txt +++ /dev/null @@ -1,250 +0,0 @@ -AFGHANISTAN AF -ÅLAND ISLANDS AX -ALBANIA AL -ALGERIA DZ -AMERICAN SAMOA AS -ANDORRA AD -ANGOLA AO -ANGUILLA AI -ANTARCTICA AQ -ANTIGUA AND BARBUDA AG -ARGENTINA AR -ARMENIA AM -ARUBA AW -AUSTRALIA AU -AUSTRIA AT -AZERBAIJAN AZ -BAHAMAS BS -BAHRAIN BH -BANGLADESH BD -BARBADOS BB -BELARUS BY -BELGIUM BE -BELIZE BZ -BENIN BJ -BERMUDA BM -BHUTAN BT -BOLIVIA, PLURINATIONAL STATE OF BO -BONAIRE, SINT EUSTATIUS AND SABA BQ -BOSNIA AND HERZEGOVINA BA -BOTSWANA BW -BOUVET ISLAND BV -BRAZIL BR -BRITISH INDIAN OCEAN TERRITORY IO -BRUNEI DARUSSALAM BN -BULGARIA BG -BURKINA FASO BF -BURUNDI BI -CAMBODIA KH -CAMEROON CM -CANADA CA -CAPE VERDE CV -CAYMAN ISLANDS KY -CENTRAL AFRICAN REPUBLIC CF -CHAD TD -CHILE CL -CHINA CN -CHRISTMAS ISLAND CX -COCOS (KEELING) ISLANDS CC -COLOMBIA CO -COMOROS KM -CONGO CG -CONGO, THE DEMOCRATIC REPUBLIC OF THE CD -COOK ISLANDS CK -COSTA RICA CR -CÔTE D'IVOIRE CI -CROATIA HR -CUBA CU -CURAÇAO CW -CYPRUS CY -CZECH REPUBLIC CZ -DENMARK DK -DJIBOUTI DJ -DOMINICA DM -DOMINICAN REPUBLIC DO -ECUADOR EC -EGYPT EG -EL SALVADOR SV -EQUATORIAL GUINEA GQ -ERITREA ER -ESTONIA EE -ETHIOPIA ET -FALKLAND ISLANDS (MALVINAS) FK -FAROE ISLANDS FO -FIJI FJ -FINLAND FI -FRANCE FR -FRENCH GUIANA GF -FRENCH POLYNESIA PF -FRENCH SOUTHERN TERRITORIES TF -GABON GA -GAMBIA GM -GEORGIA GE -GERMANY DE -GHANA GH -GIBRALTAR GI -GREECE GR -GREENLAND GL -GRENADA GD -GUADELOUPE GP -GUAM GU -GUATEMALA GT -GUERNSEY GG -GUINEA GN -GUINEA-BISSAU GW -GUYANA GY -HAITI HT -HEARD ISLAND AND MCDONALD ISLANDS HM -HOLY SEE (VATICAN CITY STATE) VA -HONDURAS HN -HONG KONG HK -HUNGARY HU -ICELAND IS -INDIA IN -INDONESIA ID -IRAN, ISLAMIC REPUBLIC OF IR -IRAQ IQ -IRELAND IE -ISLE OF MAN IM -ISRAEL IL -ITALY IT -JAMAICA JM -JAPAN JP -JERSEY JE -JORDAN JO -KAZAKHSTAN KZ -KENYA KE -KIRIBATI KI -KOREA, DEMOCRATIC PEOPLE'S REPUBLIC OF KP -KOREA, REPUBLIC OF KR -KUWAIT KW -KYRGYZSTAN KG -LAO PEOPLE'S DEMOCRATIC REPUBLIC LA -LATVIA LV -LEBANON LB -LESOTHO LS -LIBERIA LR -LIBYA LY -LIECHTENSTEIN LI -LITHUANIA LT -LUXEMBOURG LU -MACAO MO -MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OF MK -MADAGASCAR MG -MALAWI MW -MALAYSIA MY -MALDIVES MV -MALI ML -MALTA MT -MARSHALL ISLANDS MH -MARTINIQUE MQ -MAURITANIA MR -MAURITIUS MU -MAYOTTE YT -MEXICO MX -MICRONESIA, FEDERATED STATES OF FM -MOLDOVA, REPUBLIC OF MD -MONACO MC -MONGOLIA MN -MONTENEGRO ME -MONTSERRAT MS -MOROCCO MA -MOZAMBIQUE MZ -MYANMAR MM -NAMIBIA NA -NAURU NR -NEPAL NP -NETHERLANDS NL -NEW CALEDONIA NC -NEW ZEALAND NZ -NICARAGUA NI -NIGER NE -NIGERIA NG -NIUE NU -NORFOLK ISLAND NF -NORTHERN MARIANA ISLANDS MP -NORWAY NO -OMAN OM -PAKISTAN PK -PALAU PW -PALESTINE, STATE OF PS -PANAMA PA -PAPUA NEW GUINEA PG -PARAGUAY PY -PERU PE -PHILIPPINES PH -PITCAIRN PN -POLAND PL -PORTUGAL PT -PUERTO RICO PR -QATAR QA -RÉUNION RE -ROMANIA RO -RUSSIAN FEDERATION RU -RWANDA RW -SAINT BARTHÉLEMY BL -SAINT HELENA, ASCENSION AND TRISTAN DA CUNHA SH -SAINT KITTS AND NEVIS KN -SAINT LUCIA LC -SAINT MARTIN (FRENCH PART) MF -SAINT PIERRE AND MIQUELON PM -SAINT VINCENT AND THE GRENADINES VC -SAMOA WS -SAN MARINO SM -SAO TOME AND PRINCIPE ST -SAUDI ARABIA SA -SENEGAL SN -SERBIA RS -SEYCHELLES SC -SIERRA LEONE SL -SINGAPORE SG -SINT MAARTEN (DUTCH PART) SX -SLOVAKIA SK -SLOVENIA SI -SOLOMON ISLANDS SB -SOMALIA SO -SOUTH AFRICA ZA -SOUTH GEORGIA AND THE SOUTH SANDWICH ISLANDS GS -SOUTH SUDAN SS -SPAIN ES -SRI LANKA LK -SUDAN SD -SURINAME SR -SVALBARD AND JAN MAYEN SJ -SWAZILAND SZ -SWEDEN SE -SWITZERLAND CH -SYRIAN ARAB REPUBLIC SY -TAIWAN, PROVINCE OF CHINA TW -TAJIKISTAN TJ -TANZANIA, UNITED REPUBLIC OF TZ -THAILAND TH -TIMOR-LESTE TL -TOGO TG -TOKELAU TK -TONGA TO -TRINIDAD AND TOBAGO TT -TUNISIA TN -TURKEY TR -TURKMENISTAN TM -TURKS AND CAICOS ISLANDS TC -TUVALU TV -UGANDA UG -UKRAINE UA -UNITED ARAB EMIRATES AE -UNITED KINGDOM GB -UNITED STATES US -UNITED STATES MINOR OUTLYING ISLANDS UM -URUGUAY UY -UZBEKISTAN UZ -VANUATU VU -VENEZUELA, BOLIVARIAN REPUBLIC OF VE -VIET NAM VN -VIRGIN ISLANDS, BRITISH VG -VIRGIN ISLANDS, U.S. VI -WALLIS AND FUTUNA WF -WESTERN SAHARA EH -YEMEN YE -ZAMBIA ZM -ZIMBABWE ZW - diff --git a/src/legacy/local_server/install_wizard/index.php b/src/legacy/local_server/install_wizard/index.php deleted file mode 100644 index 615d238b2..000000000 --- a/src/legacy/local_server/install_wizard/index.php +++ /dev/null @@ -1,67 +0,0 @@ -. -*/ -defined('BMLT_EXEC') or die('Cannot Execute Directly'); // Makes sure that this file is in the correct context. - -$config_file_path = dirname(dirname(dirname(__FILE__))).'/server/config/get-config.php'; - -if (file_exists($config_file_path)) { - require_once($config_file_path); -} else { - die('The Config File Is Missing!'); -} - -// These are defaults for some of the newer fields. -if (!isset($region_bias) || (null === $region_bias)) { - $region_bias = 'us'; -} - -if (!isset($banner_text) || (null === $banner_text)) { - $banner_text = ''; -} - -if (!isset($comdef_global_language) || !$comdef_global_language) { - $comdef_global_language = 'en'; -} - -// We only invoke the wizard if the configuration has not been done. -if (!( - isset($dbType) && $dbType - && isset($dbName) && $dbName - && isset($dbServer) && $dbServer - && isset($dbUser) && $dbUser - && isset($dbPassword) && $dbPassword - && isset($dbPrefix) && $dbPrefix - && isset($bmlt_title) && $bmlt_title - && isset($min_pw_len) && $min_pw_len - && isset($search_spec_map_center) && is_array($search_spec_map_center) && count($search_spec_map_center) - && isset($number_of_meetings_for_auto) && $number_of_meetings_for_auto - && isset($time_format) && $time_format - && isset($change_date_format) && $change_date_format - && isset($change_depth_for_meetings) && $change_depth_for_meetings - && isset($admin_session_name) - && isset($comdef_distance_units) && $comdef_distance_units - ) - ) { - if (isset($http_vars['lang_enum']) && $http_vars['lang_enum']) { - $lang = $http_vars['lang_enum']; - } else { - $lang = isset($comdef_global_language) && $comdef_global_language ? $comdef_global_language : 'en'; - } - - require_once(dirname(__FILE__).'/installer.php'); -} diff --git a/src/legacy/local_server/install_wizard/installer.js b/src/legacy/local_server/install_wizard/installer.js deleted file mode 100644 index 44b4e4870..000000000 --- a/src/legacy/local_server/install_wizard/installer.js +++ /dev/null @@ -1,924 +0,0 @@ -/* - This file is part of the Basic Meeting List Toolbox (BMLT). - - Find out more at: https://bmlt.app - - BMLT is free software: you can redistribute it and/or modify - it under the terms of the MIT License. - - BMLT is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - MIT License for more details. - - You should have received a copy of the MIT License along with this code. - If not, see . -*/ -function BMLTInstaller( in_prefs ///< A JSON object with the initial prefs. - ) -{ - var m_installer_wrapper_object; - var m_map_object; - var m_map_center; - var m_installer_state; - var m_ajax_uri; - var m_ajax_request_in_progress; - var m_google_api_key = ""; - var m_google_maps_script = null; - var m_google_api_key_is_good = false; - var m_database_credentials_are_good = false; - var m_server_admin_password_is_good = false; - - // #mark - - // #mark Page Selection Handlers - // #mark - - - /************************************************************************************//** - * \brief Shows Page 1 of the installer wizard. It does this by setting the wrapper * - * className to the first page, which uses CSS to hide the other two pages. * - ****************************************************************************************/ - this.selectPage1 = function () { - if ( this.m_installer_wrapper_object.className != 'page_1_wrapper' ) { - this.m_installer_wrapper_object.className = 'page_1_wrapper'; - }; - }; - - /************************************************************************************//** - * \brief Shows Page 2 of the installer wizard. It does this by setting the wrapper * - * className to the first page, which uses CSS to hide the other two pages. * - ****************************************************************************************/ - this.selectPage2 = function () { - if ( this.m_installer_wrapper_object.className != 'page_2_wrapper' ) { - this.m_installer_wrapper_object.className = 'page_2_wrapper'; - }; - }; - - /************************************************************************************//** - * \brief Shows Page 3 of the installer wizard. It does this by setting the wrapper * - * className to the first page, which uses CSS to hide the other two pages. * - ****************************************************************************************/ - this.selectPage3 = function () { - if ( this.m_installer_wrapper_object.className != 'page_3_wrapper' ) { - this.m_installer_wrapper_object.className = 'page_3_wrapper'; - this.testForDatabaseSetup(); - }; - }; - - /************************************************************************************//** - * \brief Shows Page 4 of the installer wizard. It does this by setting the wrapper * - * className to the first page, which uses CSS to hide the other two pages. * - ****************************************************************************************/ - this.selectPage4 = function () { - if ( this.m_installer_wrapper_object.className != 'page_4_wrapper' ) { - this.m_installer_wrapper_object.className = 'page_4_wrapper'; - document.getElementById('database_install_stuff_div').className = 'item_hidden'; - document.getElementById('file_text_pre').innerHTML = this.createFileData(); - var apiKeyWarningDiv = document.getElementById('admin_google_api_key_warning'); - var testForDatabaseSetup = this.testForDatabaseSetup; - if (apiKeyWarningDiv) { - this.testMapsApiKey(function (message) { - if (message) { - apiKeyWarningDiv.innerHTML = g_maps_api_key_warning + ' ' + message + '
' + g_maps_api_key_click_here + ''; - this.m_google_api_key_is_good = false; - } else { - apiKeyWarningDiv.innerHTML = ''; - this.m_google_api_key_is_good = true; - } - testForDatabaseSetup.call(g_installer_object); - }); - } - } - }; - - // #mark - - // #mark Text Item Handlers - // #mark - - - /************************************************************************************//** - * \brief When a text input (either or '; - $ret .= ''; - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['user_editor_account_email_label']).''; - $ret .= ''; - $ret .= ''; - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= ''; - $ret .= ''; - $ret .= '
'; - $ret .= '
'.(defined('__DEBUG_MODE__') ? "\n" : ''); - $ret .= $this->return_user_editor_button_panel(); - $ret .= ''.(defined('__DEBUG_MODE__') ? "\n" : ''); - $ret .= '
'.(defined('__DEBUG_MODE__') ? "\n" : ''); - $ret .= ''.(defined('__DEBUG_MODE__') ? "\n" : ''); - - return $ret; - } - - /********************************************************************************************************//** - \brief This creates the HTML for a user selection popup menu. - \returns The HTML and JavaScript for the popup menu (select element). - ************************************************************************************************************/ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function create_user_popup($users) - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $ret = ''.(defined('__DEBUG_MODE__') ? "\n" : ''); - - return $ret; - } - - /********************************************************************************************************//** - \brief This creates the HTML for a user level popup menu. - \returns The HTML and JavaScript for the popup menu (select element). - ************************************************************************************************************/ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function create_user_level_popup() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $disabled = $this->my_user->GetUserLevel() == _USER_LEVEL_SERVER_ADMIN ? '' : ' disabled'; - $ret = ''; - - return $ret; - } - - /********************************************************************************************************//** - \brief This creates the HTML for a user owner selection popup menu. - \returns The HTML and JavaScript for the popup menu (select element). - ************************************************************************************************************/ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function create_user_owner_popup($users) - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $disabled = $this->my_user->GetUserLevel() == _USER_LEVEL_SERVER_ADMIN ? '' : ' disabled'; - $ret = ''.(defined('__DEBUG_MODE__') ? "\n" : ''); - - return $ret; - } - - /********************************************************************************************************//** - \brief This constructs the User editor buttons as a div. - \returns The HTML and JavaScript for the button panel. - ************************************************************************************************************/ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function return_user_editor_button_panel() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $ret = '
'; - $ret .= ''; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['user_save_button']).''; - $ret .= 'AJAX Throbber'; - $ret .= ''; - $ret .= ''; - $delete_button_href = $this->my_user->GetUserLevel() == _USER_LEVEL_SERVER_ADMIN ? 'javascript:admin_handler_object.deleteUser();' : 'javascript:void(0);'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['user_delete_button']).''; - $ret .= 'AJAX Throbber'; - $ret .= ''; - $delete_perm_checkbox_disabled = $this->my_user->GetUserLevel() == _USER_LEVEL_SERVER_ADMIN ? '' : 'disabled '; - $ret .= ''; - $ret .= ''; - $ret .= ''; - $ret .= ''; - $ret .= ''; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['user_cancel_button']).''; - $ret .= ''; - $ret .= '
'; - $ret .= '
'; - - return $ret; - } - - /********************************************************************************************************//** - \brief This constructs the Service body editor panel. Only Server Admins and Service Body Admins get this one. - \returns The HTML and JavaScript for the "Service Body Administration" section. - ************************************************************************************************************/ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function return_service_body_admin_panel() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $ret = ''; - $full_editors = $this->get_full_editor_users(); - - if (count($full_editors)) { // Have to have at least one Service body admin - $ret = '
'.(defined('__DEBUG_MODE__') ? "\n" : ''); - $ret .= ''; - $ret .= htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['service_body_editor_disclosure']); - $ret .= ''.(defined('__DEBUG_MODE__') ? "\n" : ''); - $ret .= '
'.(defined('__DEBUG_MODE__') ? "\n" : ''); - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['need_refresh_message_fader_text']).''; - $ret .= '
'.(defined('__DEBUG_MODE__') ? "\n" : ''); - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['service_body_change_fader_success_text']).''; - $ret .= '
'.(defined('__DEBUG_MODE__') ? "\n" : ''); - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['service_body_change_fader_fail_text']).''; - $ret .= '
'.(defined('__DEBUG_MODE__') ? "\n" : ''); - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['service_body_change_fader_create_success_text']).''; - $ret .= '
'.(defined('__DEBUG_MODE__') ? "\n" : ''); - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['service_body_change_fader_create_fail_text']).''; - $ret .= '
'.(defined('__DEBUG_MODE__') ? "\n" : ''); - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['service_body_change_fader_delete_success_text']).''; - $ret .= '
'.(defined('__DEBUG_MODE__') ? "\n" : ''); - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['service_body_change_fader_delete_fail_text']).''; - $ret .= '
'.(defined('__DEBUG_MODE__') ? "\n" : ''); - $ret .= '
'; - $ret .= '
'; - - $ret .= $this->return_single_service_body_editor_panel(); - $ret .= '
'; - $ret .= ''; - } - - return $ret; - } - - /********************************************************************************************************//** - \brief This constructs a window for the Service Body administrator. - \returns The HTML and JavaScript for the "Service Body Administration" section. - ************************************************************************************************************/ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function return_single_service_body_editor_panel() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $ret = '
'.(defined('__DEBUG_MODE__') ? "\n" : ''); - $ret .= '
'.(defined('__DEBUG_MODE__') ? "\n" : ''); - $ret .= ''.(defined('__DEBUG_MODE__') ? "\n" : ''); - - if (!($this->my_user->GetUserLevel() == _USER_LEVEL_SERVER_ADMIN) && count($this->my_editable_service_bodies) == 1) { - $ret .= ''.htmlspecialchars($this->my_editable_service_bodies[0]->GetLocalName()).''; - } else { - $ret .= $this->create_service_body_popup(); - } - - $ret .= ''.(defined('__DEBUG_MODE__') ? "\n" : ''); - $ret .= ''; - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['service_body_editor_screen_sb_id_label']).''; - $ret .= ''; - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['service_body_editor_screen_sb_admin_user_label']).''; - - if ($this->my_user->GetUserLevel() == _USER_LEVEL_SERVER_ADMIN) { - $ret .= ''; - $ret .= $this->create_service_body_user_popup(); - $ret .= ''; - } else { - $ret .= ''; - } - $ret .= '
'; - $ret .= '
'; - if ($this->my_user->GetUserLevel() == _USER_LEVEL_SERVER_ADMIN) { - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['service_body_editor_type_label']).''; - $ret .= ''; - $ret .= $this->create_service_body_type_popup(); - $ret .= ''; - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['service_body_parent_popup_label']).''; - $ret .= ''; - $ret .= $this->create_service_body_parent_popup(); - $ret .= ''; - $ret .= '
'; - $ret .= '
'; - - // This is the part of the form that allows us to import a list of IDs from NAWS, and replace them in our database. - if (defined('__NAWS_IMPORT__')) { - $ret .= '
'; - $ret .= '
'; - } - } - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['service_body_editor_screen_sb_name_label']).''; - $ret .= ''; - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['service_body_editor_screen_sb_admin_description_label']).''; - $ret .= ''; - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['service_body_editor_screen_sb_admin_email_label']).''; - $ret .= ''; - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['service_body_editor_screen_sb_admin_uri_label']).''; - $ret .= ''; - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['service_body_editor_screen_world_cc_label']).''; - $ret .= ''; - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['service_body_editor_screen_helpline_label']).''; - $ret .= ''; - $ret .= '
'; - $ret .= '
'; - - $full_editors = $this->get_full_editor_users(); - $basic_editors = $this->get_basic_editor_users(); - $observers = $this->get_observer_users(); - - if (count($full_editors)) { - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['service_body_editor_screen_sb_admin_full_editor_label']).''; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['service_body_editor_screen_sb_admin_full_editor_desc']).''; - $ret .= '
'; - - foreach ($full_editors as $user) { - $ret .= ''; - $ret .= ''; - $ret .= '
'; - } - - $ret .= '
'; - $ret .= '
'; - } - - if (count($observers)) { - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['service_body_editor_screen_sb_admin_observer_label']).''; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['service_body_editor_screen_sb_admin_observer_desc']).''; - $ret .= '
'; - - foreach ($observers as $user) { - $ret .= ''; - $ret .= ''; - $ret .= '
'; - } - $ret .= '
'; - $ret .= '
'; - } - - $ret .= '
'; - $ret .= $this->return_service_body_editor_button_panel(); - $ret .= '
'.(defined('__DEBUG_MODE__') ? "\n" : ''); - $ret .= '
'.(defined('__DEBUG_MODE__') ? "\n" : ''); - - return $ret; - } - - /********************************************************************************************************//** - \brief This gets just the Service Body Admin Users, and returns their objects in an array. - \returns An array with the user objects (instances of c_comdef_user) - ************************************************************************************************************/ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function get_full_editor_users() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $ret = array (); - - for ($c = 0; $c < count($this->my_users); $c++) { - $user = $this->my_users[$c]; - if ($user->GetUserLevel() == _USER_LEVEL_SERVICE_BODY_ADMIN) { - array_push($ret, $user); - } - } - - return $ret; - } - - /********************************************************************************************************//** - \brief This gets just the Service Body Editor (Trainee) Users, and returns their objects in an array. - \returns An array with the user objects (instances of c_comdef_user) - ************************************************************************************************************/ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function get_basic_editor_users() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $ret = array (); - - for ($c = 0; $c < count($this->my_users); $c++) { - $user = $this->my_users[$c]; - if ($user->GetUserLevel() == _USER_LEVEL_EDITOR) { - array_push($ret, $user); - } - } - - return $ret; - } - - /********************************************************************************************************//** - \brief This gets just the Observer Users, and returns their objects in an array. - \returns An array with the user objects (instances of c_comdef_user) - ************************************************************************************************************/ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function get_observer_users() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $ret = array (); - - for ($c = 0; $c < count($this->my_users); $c++) { - $user = $this->my_users[$c]; - if ($user->GetUserLevel() == _USER_LEVEL_OBSERVER) { - array_push($ret, $user); - } - } - - return $ret; - } - - /********************************************************************************************************//** - \brief This creates the HTML for a Service body parent selection popup menu. - \returns The HTML and JavaScript for the popup menu (select element). - ************************************************************************************************************/ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function create_service_body_parent_popup() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $ret = ''.(defined('__DEBUG_MODE__') ? "\n" : ''); - - return $ret; - } - - /********************************************************************************************************//** - \brief This creates the HTML for a Service body selection popup menu. - \returns The HTML and JavaScript for the popup menu (select element). - ************************************************************************************************************/ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function create_service_body_popup() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $ret = ''.(defined('__DEBUG_MODE__') ? "\n" : ''); - - return $ret; - } - - /********************************************************************************************************//** - \brief This creates the HTML for a Service body selection popup menu. - \returns The HTML and JavaScript for the popup menu (select element). - ************************************************************************************************************/ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function create_service_body_type_popup() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $ret = ''; - - return $ret; - } - - /********************************************************************************************************//** - \brief This returns the user name for a given user ID. - \returns a string, containing the name. - ************************************************************************************************************/ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function get_user_name_from_id( - $in_user_id ///< The ID to look up. - ) { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $ret = null; - - for ($index = 0; $index < count($this->my_users); $index++) { - $user = $this->my_users[$index]; - if ($user->GetID() == $in_user_id) { - $ret = $user->GetLocalName(); - break; - } - } - - return $ret; - } - - /********************************************************************************************************//** - \brief This creates the HTML for a Service body selection popup menu. - \returns The HTML and JavaScript for the popup menu (select element). - ************************************************************************************************************/ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function create_service_body_user_popup() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $ret = ''; - - return $ret; - } - - /********************************************************************************************************//** - \brief This constructs the Service body editor buttons as a div. - \returns The HTML and JavaScript for the button panel. - ************************************************************************************************************/ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function return_service_body_editor_button_panel() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $ret = '
'; - $ret .= ''; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['service_body_save_button']).''; - $ret .= 'AJAX Throbber'; - $ret .= ''; - if ($this->my_user->GetUserLevel() == _USER_LEVEL_SERVER_ADMIN) { - $ret .= ''; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['service_body_delete_button']).''; - $ret .= 'AJAX Throbber'; - $ret .= ''; - $ret .= ''; - $ret .= ''; - $ret .= ''; - $ret .= ''; - } - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['service_body_cancel_button']).''; - $ret .= '
'; - $ret .= '
'; - - return $ret; - } - - /********************************************************************************************************//** - \brief This constructs the meeting editor section of the console. Most user levels (not observers) have it. - \returns The HTML and JavaScript for the "Edit Meetings" section. - ************************************************************************************************************/ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function return_meeting_editor_panel() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $ret = ''; - - $can_edit = false; - - for ($c = 0; $c < count($this->my_service_bodies); $c++) { - if ($this->my_service_bodies[$c]->UserCanEditMeetings()) { - $can_edit = true; - } - } - - if ($can_edit) { - $ret = ''; - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['need_refresh_message_fader_text']).''; - $ret .= '
'.(defined('__DEBUG_MODE__') ? "\n" : ''); - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_change_fader_success_text']).''; - $ret .= '
'; - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_change_fader_success_delete_text']).''; - $ret .= '
'; - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_change_fader_success_add_text']).''; - $ret .= '
'; - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_change_fader_fail_delete_text']).''; - $ret .= '
'; - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_change_fader_failure_text']).''; - $ret .= '
'; - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_change_fader_fail_add_text']).''; - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - $ret .='
'; - $ret .= $this->return_meeting_editor_tab_div(); - $ret .= '
'; - $ret .='
'; - $ret .= $this->return_meeting_specification_panel(); - $ret .= $this->return_meeting_editor_meetings_panel(); - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - } - - return $ret; - } - - /********************************************************************************************************//** - \brief This constructs the tab div that allows the user to select between a search and results. - \returns The HTML and JavaScript for the Meeting Editor Tabs - ************************************************************************************************************/ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function return_meeting_editor_tab_div() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $ret =''; - $ret .=''; - $ret .= '
'; - return $ret; - } - - /********************************************************************************************************//** - \brief This constructs the meeting search specification panel of the meeting editor. - \returns The HTML and JavaScript for the Edit Meetings Search Specifier section. - ************************************************************************************************************/ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function return_meeting_specification_panel() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $ret = '
'; - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_text_input_label']).''; - $ret .= ''; - $ret .= ''; - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= ''; - $ret .= ''; - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_search_weekdays_label']).''; - $ret .= '
'; - for ($c = 0; $c < 8; $c++) { - $ret .= ''; - $ret .= ''.(defined('__DEBUG_MODE__') ? "\n" : ''); - $ret .= ''.(defined('__DEBUG_MODE__') ? "\n" : ''); - $ret .= ''; - } - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= $this->return_meeting_start_time_selection_panel(); - if (count($this->my_service_bodies) > 1) { - $ret .= $this->return_meeting_service_body_selection_panel(); - } - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_editor_screen_meeting_publish_search_prompt']).''; - $ret .= '
'; - $ret .= ''; - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= ' '; - $ret .= ''; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_editor_tab_specifier_text']).''; - $ret .= ''; - $ret .= 'AJAX Throbber'; - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - - return $ret; - } - - /********************************************************************************************************//** - \brief This constructs a panel that displays a choice of Service bodies for the user to choose. - \returns The HTML and JavaScript for the Edit Meetings Search Specifier section. - ************************************************************************************************************/ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function return_meeting_start_time_selection_panel() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $ret = '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_search_start_time_label']).''; - $ret .= '
'; - $ret .= ''; - $ret .= ''; - $ret .= ''; - $ret .= ''; - $ret .= ''; - $ret .= ''; - $ret .= ''; - $ret .= ''; - $ret .= ''; - $ret .= ''; - $ret .= ''; - $ret .= ''; - $ret .= ''; - $ret .= ''; - $ret .= ''; - $ret .= ''; - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - - return $ret; - } - - /********************************************************************************************************//** - \brief This constructs a panel that displays a choice of Service bodies for the user to choose. - \returns The HTML and JavaScript for the Edit Meetings Search Specifier section. - ************************************************************************************************************/ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function return_meeting_service_body_selection_panel() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $ret = 'NOT AUTHORIZED'; - - if (count($this->my_service_bodies)) { - $ret = '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_search_service_bodies_label']).''; - $ret .= '
'; - $ret .= '
'; - $ret .= ''; - $ret .= '
'; - $ret .= $this->populate_service_bodies(0); - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - } - - return $ret; - } - - /************************************************************************************//** - \brief Build the content for the Advanced Service Bodies section. - ****************************************************************************************/ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function populate_service_bodies( - $in_id ///< The ID of the Service body. - ) { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $service_body_content = ''; - $child_content = ''; - - foreach ($this->my_all_service_bodies as $service_body) { - if ($in_id == $service_body->GetID()) { - if ($service_body->UserCanEditMeetings()) { - $service_body_content = ''; - $service_body_content .= ''; - $service_body_content .= ''; - $service_body_content .= ''; - } - } elseif ($in_id == $service_body->GetOwnerID()) { - $child_content .= $this->populate_service_bodies($service_body->GetID()); - } - } - - // At this point, we have the main Service body, as well as any child content. - - if ($service_body_content) { - $service_body_content = '
'.$service_body_content.'
'.(defined('__DEBUG_MODE__') ? "\n" : ''); - } - - if ($child_content) { - $child_content = '
'.$child_content.'
'.(defined('__DEBUG_MODE__') ? "\n" : ''); - } - - $ret = ''; - - if ($service_body_content || $child_content) { - $ret = '
'.(defined('__DEBUG_MODE__') ? "\n" : '').$service_body_content.(defined('__DEBUG_MODE__') ? "\n" : '').$child_content.'
'.(defined('__DEBUG_MODE__') ? "\n" : ''); - } - - return $ret; - } - - /********************************************************************************************************//** - \brief This constructs the combined new meetings/search results panel. - \returns The HTML and JavaScript for the Edit Meetings Search Results section. - ************************************************************************************************************/ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function return_meeting_editor_meetings_panel() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - if (($this->my_user->GetUserLevel() == _USER_LEVEL_EDITOR) || ($this->my_user->GetUserLevel() == _USER_LEVEL_SERVICE_BODY_ADMIN) || ($this->my_user->GetUserLevel() == _USER_LEVEL_SERVER_ADMIN)) { - $ret = '
'; - $ret .= '
'; - $ret .= $this->return_single_meeting_editor_template(); - $ret .= $this->return_new_meeting_panel(); - $ret .= $this->return_meeting_results_panel(); - $ret .= '
'; - $ret .= '
'; - } else { - die('THIS USER NOT AUTHORIZED TO EDIT MEETINGS'); - } - - return $ret; - } - - /********************************************************************************************************//** - \brief This constructs a panel for creating new meetings that goes above the results. - \returns The HTML and JavaScript for the New Meetings section. - ************************************************************************************************************/ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function return_new_meeting_panel() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $ret = '
'; - $ret .= '
'; - $ret .= ''; - $ret .= '
'; - $ret .= '
'; - - return $ret; - } - - /********************************************************************************************************//** - \brief This constructs the meeting search results panel of the meeting editor. - \returns The HTML and JavaScript for the Search Results section. - ************************************************************************************************************/ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function return_meeting_results_panel() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $ret = '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - - return $ret; - } - - /********************************************************************************************************//** - \brief This constructs a template to be filled in for a single meeting that will be edited. - \returns The HTML and JavaScript for the "Edit Meetings" section. - ************************************************************************************************************/ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function return_single_meeting_editor_template() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $ret = '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= ''; - $ret .= $this->return_meeting_editor_button_panel(); - $ret .= '
'; - $ret .= '
'; - - return $ret; - } - - /********************************************************************************************************//** - \brief This constructs the meeting editor buttons as a div. - \returns The HTML and JavaScript for the button panel. - ************************************************************************************************************/ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function return_meeting_editor_button_panel() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $ret = '
'; - $ret .= ''; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_save_buttonName']).''; - $ret .= 'AJAX Throbber'; - $ret .= ''; - $ret .= ''; - $ret .= ''; - $ret .= ''; - $ret .= ''; - $ret .= ''; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_editor_screen_delete_button']).''; - $ret .= 'AJAX Throbber'; - $ret .= ''; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_editor_screen_cancel_button']).''; - $ret .= '
'; - $ret .= '
'; - - return $ret; - } - - /********************************************************************************************************//** - \brief This constructs a template to be filled in for the basic options tab. - \returns The HTML and JavaScript for the option sheet. - ************************************************************************************************************/ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function return_single_meeting_basic_template() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - if (($this->my_user->GetUserLevel() == _USER_LEVEL_EDITOR) || ($this->my_user->GetUserLevel() == _USER_LEVEL_SERVICE_BODY_ADMIN) || ($this->my_user->GetUserLevel() == _USER_LEVEL_SERVER_ADMIN)) { - $ret = '
'; - - if ($this->my_user->GetUserLevel() != _USER_LEVEL_EDITOR) { - $ret .= '
'; - $ret .= ''; - $ret .= ''; - $ret .= '
'; - $ret .= '
'; - - $ret .= '
'; - $ret .= ' '; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_unpublished_note']).''; - $ret .= '
'; - $ret .= '
'; - } - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_id_label']).''; - $ret .= ''; - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_editor_screen_meeting_name_label']).''; - $ret .= '
' . htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_editor_screen_meeting_name_prompt']) . '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_editor_screen_meeting_weekday_label']).''; - $ret .= ''; - $ret .= ''; - $ret .= ''; - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_editor_screen_meeting_start_label']).''; - $ret .= ''; - $ret .= ''; - $ret .= ':'; - $ret .= ''; - $ret .= ''; - $ret .= ''; - $ret .= ''; - $ret .= ''; - $ret .= ''; - $ret .= ''; - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_editor_screen_meeting_duration_label']).''; - $ret .= ''; - $ret .= ''; - $ret .= ':'; - $ret .= ''; - $ret .= ''; - $ret .= ''; - $ret .= '
'; - $ret .= '
'; - - if ($this->my_localized_strings['meeting_time_zones_enabled']) { - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_editor_screen_meeting_time_zone_label']).''; - $ret .= ''; - $ret .= ''; - $ret .= ''; - $ret .= '
'; - $ret .= '
'; - } - - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_editor_screen_meeting_cc_label']).''; - $ret .= '
' . '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_editor_screen_meeting_cc_advice']).''; - $ret .= '
'; - $ret .= '
'; - - if (count($this->my_service_bodies) > 1) { - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_editor_screen_meeting_sb_label']).''; - $ret .= ''; - $ret .= ''; - $ret .= ''; - $ret .= '
'; - $ret .= '
'; - } - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_editor_screen_meeting_contact_label']).''; - $ret .= '
' . htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_editor_screen_meeting_contact_prompt']) . '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_editor_screen_meeting_visibility_advice']).''; - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - } - - return $ret; - } - - /********************************************************************************************************//** - \brief This constructs a template to be filled in for the location options tab. - \returns The HTML and JavaScript for the option sheet. - ************************************************************************************************************/ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function return_single_meeting_location_template() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $ret = '
'; - $ret .= ''; - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_editor_screen_meeting_venue_type']).''; - $ret .= ''; - $ret .= ''; - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_editor_screen_meeting_longitude_label']).''; - $ret .= 'my_localized_strings['auto_geocoding_enabled'] ? 'readonly' : '') . '/>
' . htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_editor_screen_meeting_longitude_prompt']) . '
'; - if ($this->my_localized_strings['auto_geocoding_enabled']) { - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['automatically_calculated_on_save']).''; - } - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_editor_screen_meeting_latitude_label']).''; - $ret .= 'my_localized_strings['auto_geocoding_enabled'] ? 'readonly' : '') . ' />
' . htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_editor_screen_meeting_latitude_prompt']) . '
'; - if ($this->my_localized_strings['auto_geocoding_enabled']) { - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['automatically_calculated_on_save']).''; - } - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_editor_screen_meeting_location_label']).''; - $ret .= '
' . htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_editor_screen_meeting_location_prompt']) . '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_editor_screen_meeting_info_label']).''; - $ret .= '
' . htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_editor_screen_meeting_info_prompt']) . '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_editor_screen_meeting_street_label']).''; - $ret .= '
' . htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_editor_screen_meeting_street_prompt']) . '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_editor_screen_meeting_neighborhood_label']).''; - $ret .= '
' . htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_editor_screen_meeting_neighborhood_prompt']) . '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_editor_screen_meeting_borough_label']).''; - $ret .= '
' . htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_editor_screen_meeting_borough_prompt']). '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_editor_screen_meeting_city_label']).''; - $ret .= '
' . htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_editor_screen_meeting_city_prompt']) . '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_editor_screen_meeting_county_label']).''; - $ret .= ''; - if ((!$this->my_localized_strings['auto_geocoding_enabled'] || !$this->my_localized_strings['county_auto_geocoding_enabled']) && is_array($this->my_localized_strings['meeting_counties_and_sub_provinces']) && count($this->my_localized_strings['meeting_counties_and_sub_provinces'])) { - $ret .= ''; - } else { - $ret .= 'my_localized_strings['auto_geocoding_enabled'] && $this->my_localized_strings['county_auto_geocoding_enabled'] ? 'readonly' : '') . ' />'; - } - $ret .= '
' . htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_editor_screen_meeting_county_prompt']) . '
'; - if ($this->my_localized_strings['auto_geocoding_enabled'] && $this->my_localized_strings['county_auto_geocoding_enabled']) { - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['automatically_calculated_on_save']).''; - } - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_editor_screen_meeting_state_label']).''; - $ret .= ''; - if (is_array($this->my_localized_strings['meeting_states_and_provinces']) && count($this->my_localized_strings['meeting_states_and_provinces'])) { - $ret .= ''; - } else { - $ret .= ''; - } - $ret .= '
' . htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_editor_screen_meeting_state_prompt']) . '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_editor_screen_meeting_zip_label']).''; - $ret .= 'my_localized_strings['auto_geocoding_enabled'] && $this->my_localized_strings['zip_auto_geocoding_enabled'] ? 'readonly' : '') . '/>
' . htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_editor_screen_meeting_zip_prompt']) . '
'; - if ($this->my_localized_strings['auto_geocoding_enabled'] && $this->my_localized_strings['zip_auto_geocoding_enabled']) { - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['automatically_calculated_on_save']).''; - } - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_editor_screen_meeting_nation_label']).''; - $ret .= '
' . htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_editor_screen_meeting_nation_prompt']).'
'; - $ret .= '
'; - $ret .= '
'; - - $ret .= '
'; - $ret .= ''; - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_editor_screen_meeting_phone_meeting_number_label']).''; - $ret .= '
' . htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_editor_screen_meeting_phone_meeting_number_prompt']) . '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_editor_screen_meeting_virtual_meeting_link_label']).''; - $ret .= '
' . htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_editor_screen_meeting_virtual_meeting_link_prompt']) . '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_editor_screen_meeting_virtual_meeting_additional_info_label']).''; - $ret .= '
' . htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_editor_screen_meeting_virtual_meeting_additional_info_prompt']) . '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - - return $ret; - } - public function getDisplayTextForFormatTypeKey($type) - { - if (isset($this->my_localized_strings['comdef_server_admin_strings']['format_type_codes'][$type->getKey()])) { - return $this->my_localized_strings['comdef_server_admin_strings']['format_type_codes'][$type->GetKey()]; - } - return $this->my_localized_strings['comdef_server_admin_strings']['unknown_format_type']. - $type->GetApiEnum(); - } - /********************************************************************************************************//** - \brief - \returns The HTML and JavaScript for the option sheet. - ************************************************************************************************************/ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function return_single_meeting_format_template() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $ret = '
'; - $ret .= '
'; - $f_array = $this->my_server->GetFormatsArray(); - $f_array = $f_array[$this->my_server->GetLocalLang()]; - if ($this->my_localized_strings['sort_formats']) { - usort($f_array, function ($a, $b) { - return strnatcasecmp($a->GetKey(), $b->GetKey()); - }); - } - $formats_by_formattype = array(); - foreach ($f_array as $format) { - $type = $format->GetFormatType(); - if (is_null($type)) { - $type = ''; - } else if (strpos($type, '-')>0) { - $type = substr($type, 0, strpos($type, '-')); - } - if (!isset($formats_by_formattype[$type])) { - $formats_by_formattype[$type] = array(); - } - $formats_by_formattype[$type][] = $format; - } - foreach ($this->my_format_types as $format_type) { - if (isset($formats_by_formattype[$format_type->getKey()])) { - $ret .= '
'; - $ret .= '
'.$this->getDisplayTextForFormatTypeKey($format_type).'
'; - $ret .= $this->format_type_section_checkboxes($formats_by_formattype[$format_type->getKey()]); - unset($formats_by_formattype[$format_type->getKey()]); - $ret .= '
'; - } - } - if (count($formats_by_formattype) > 0) { - $ret .= '
'; - $ret .= '
'.$this->my_localized_strings['comdef_server_admin_strings']['other_or_empty_format_type'].'
'; - - foreach ($formats_by_formattype as $format_array) { - $ret .= $this->format_type_section_checkboxes($format_array); - } - $ret .= '
'; - } - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - - return $ret; - } - /********************************************************************************************************//** - \brief - \returns The HTML and JavaScript for the option sheet. - ************************************************************************************************************/ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - private function format_type_section_checkboxes($formats) - { - $ret = ''; - foreach ($formats as $format) { - $ret .= '
'; - $ret .= ''; - $ret .= ''; - $ret .= ''; - $ret .= '
'; - } - return $ret; - } - /********************************************************************************************************//** - \brief - \returns The HTML and JavaScript for the option sheet. - ************************************************************************************************************/ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function return_single_meeting_other_template() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $ret = '
'; - foreach ($this->my_data_field_templates as $data_field) { - $key = $data_field['key']; - $prompt = $data_field['field_prompt']; - switch ($key) { - case 'id_bigint': // All of these are ignored, as they are taken care of in other option sheets. - case 'worldid_mixed': - case 'shared_group_id_bigint': - case 'service_body_bigint': - case 'weekday_tinyint': - case 'venue_type': - case 'start_time': - case 'formats': - case 'lang_enum': - case 'longitude': - case 'latitude': - case 'email_contact': - case 'meeting_name': - case 'location_text': - case 'location_info': - case 'location_street': - case 'location_neighborhood': - case 'location_city_subsection': - case 'location_municipality': - case 'location_sub_province': - case 'location_province': - case 'location_postal_code_1': - case 'location_nation': - case 'phone_meeting_number': - case 'virtual_meeting_link': - case 'virtual_meeting_additional_info': - break; - - default: // We display these ones. - if (array_key_exists('meeting_editor_screen_meeting_' . $key . '_label', $this->my_localized_strings['comdef_server_admin_strings'])) { - $prompt = $this->my_localized_strings['comdef_server_admin_strings']['meeting_editor_screen_meeting_' . $key . '_label']; - } - $ret .= '
'; - $ret .= ''.htmlspecialchars($prompt).''; - $ret .= ''; - $ret .= ''; - $ret .= ''; - if ($data_field['visibility'] == _VISIBILITY_NONE_) { - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['meeting_editor_screen_meeting_visibility_advice']).''; - } - $ret .= '
'; - $ret .= '
'; - break; - } - } - $ret .= '
'; - - return $ret; - } - - /********************************************************************************************************//** - \brief - \returns The HTML and JavaScript for the option sheet. - ************************************************************************************************************/ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function return_single_meeting_history_template() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $ret = '
'; - $ret .= '
AJAX Throbber
'; - $ret .= '
'; - - return $ret; - } - - /********************************************************************************************************//** - \brief This constructs the "Server Administration" section of the console. Server Admins and Service Body admins can see this. - \returns The HTML and JavaScript for the "Server Administration" section. - ************************************************************************************************************/ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function return_server_admin_panel() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $ret = ''; - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - - - $ret .= '
'; - $ret .= '
'; - $ret .= ''; - // Put the select menu, or "popup", here - if ($this->my_user->GetUserLevel() == _USER_LEVEL_SERVER_ADMIN) { - $ret .= ''; - } else { - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['update_world_ids_from_spreadsheet_dropdown_text']).''; - } - $ret .= ''; - - // World IDs update - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['server_admin_naws_spreadsheet_label']).''; - $ret .= ''; - $ret .= ''; - $ret .= ''; - $ret .= '
'; - $ret .= ''; - $ret .= '
'; - $ret .= '
'; - - // NAWS Import - $ret .= '
'; - $ret .= '
'; - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['server_admin_naws_import_spreadsheet_label']).''; - $ret .= ''; - $ret .= ''; - $ret .= ''; - $ret .= '
'; - $ret .= '
'; - $ret .= ''.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['server_admin_naws_import_initially_publish']).''; - $ret .= ''; - $ret .= ''; - $ret .= ''; - $ret .= '  '.htmlspecialchars($this->my_localized_strings['comdef_server_admin_strings']['server_admin_naws_import_explanation']).''; - $ret .= '
'; - $ret .= ''; - $ret .= '
'; - $ret .= '
'; - - - - $ret .= '
'; - $ret .= '
'; - - $ret .= '
'; - - return $ret; - } - - /********************************************************************************************************//** - \brief This constructs the "My Account" section of the console. All user levels will have this. - \returns The HTML and JavaScript for the "My Account" section. - ************************************************************************************************************/ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function return_user_account_settings_panel() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $ret = ''; - $ret .= ''; - - return $ret; - } - - /************************************************************************************//** - \brief Used to sort users and service body names. - ****************************************************************************************/ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function compare_names($a, $b) - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - return strnatcasecmp($a->GetLocalName(), $b->GetLocalName()); - } -} diff --git a/src/legacy/local_server/server_admin/c_comdef_admin_xml_handler.class.php b/src/legacy/local_server/server_admin/c_comdef_admin_xml_handler.class.php deleted file mode 100644 index 0346d8011..000000000 --- a/src/legacy/local_server/server_admin/c_comdef_admin_xml_handler.class.php +++ /dev/null @@ -1,1880 +0,0 @@ -. -*/ -defined('BMLT_EXEC') or die('Cannot Execute Directly'); // Makes sure that this file is in the correct context. -/***********************************************************************************************************//** - \class c_comdef_admin_xml_handler - \brief Controls handling of the admin semantic interface. - - This class should not even be instantiated unless the user has been authorized, and an authorized seesion - is in progress. -***************************************************************************************************************/ -// phpcs:disable PSR1.Classes.ClassDeclaration.MissingNamespace -// phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps -class c_comdef_admin_xml_handler -// phpcs:enable PSR1.Classes.ClassDeclaration.MissingNamespace -// phpcs:enable Squiz.Classes.ValidClassName.NotCamelCaps -{ - public $http_vars; ///< This will hold the combined GET and POST parameters for this call. - public $server; ///< The BMLT server model instance. - public $my_localized_strings; ///< An array of localized strings. - public $handled_service_body_ids; ///< This is used to ensure that we respect the hierarchy when doing a hierarchical Service body request. - - /********************************************************************************************************//** - \brief The class constructor. - ************************************************************************************************************/ - public function __construct( - $in_http_vars, ///< The combined GET and POST parameters. - $in_server ///< The BMLT server instance. - ) { - $this->http_vars = $in_http_vars; - $this->server = $in_server; - $this->my_localized_strings = c_comdef_server::GetLocalStrings(); - $this->handled_service_body_ids = array(); - } - - /********************************************************************************************************//** - \brief This returns the URL to the main server. It needs extra stripping, because we're depper than usual. - - \returns the URL. - ************************************************************************************************************/ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function getMainURL() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - return dirname(dirname(GetURLToMainServerDirectory(false))).'/'; - } - - /********************************************************************************************************//** - \brief This extracts a meeting's essential data as XML. - - \returns the XML for the meeting data. - ************************************************************************************************************/ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function get_meeting_data($meeting_id) - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $ret = ''; - - $meeting_object = c_comdef_server::GetOneMeeting($meeting_id); - - if (($meeting_object instanceof c_comdef_meeting) && (intval($meeting_object->GetID()) == intval($meeting_id))) { - $localized_strings = c_comdef_server::GetLocalStrings(); - $meeting_id = $meeting_object->GetID(); - $weekday_tinyint = intval($meeting_object->GetMeetingDataValue('weekday_tinyint')); - $weekday_name = $localized_strings["comdef_server_admin_strings"]["meeting_search_weekdays_names"][$weekday_tinyint]; - $start_time = $meeting_object->GetMeetingDataValue('start_time'); - $meeting_name = str_replace('"', "'", str_replace("\n", " ", str_replace("\r", " ", $meeting_object->GetMeetingDataValue('meeting_name')))); - $meeting_borough = str_replace('"', "'", str_replace("\n", " ", str_replace("\r", " ", $meeting_object->GetMeetingDataValue('location_city_subsection')))); - $meeting_town = str_replace('"', "'", str_replace("\n", " ", str_replace("\r", " ", $meeting_object->GetMeetingDataValue('location_municipality')))); - $meeting_state = str_replace('"', "'", str_replace("\n", " ", str_replace("\r", " ", $meeting_object->GetMeetingDataValue('location_province')))); - - $ret = '"meeting_id","meeting_name","weekday_tinyint","weekday_name","start_time","location_city_subsection","location_municipality","location_province"'."\n"; - - if ($meeting_id) { - $change_line['meeting_id'] = $meeting_id; - } else { - $change_line['meeting_id'] = 0; - } - - if ($meeting_name) { - $change_line['meeting_name'] = $meeting_name; - } else { - $change_line['meeting_name'] = ''; - } - - if ($weekday_tinyint) { - $change_line['weekday_tinyint'] = $weekday_tinyint; - } else { - $change_line['weekday_tinyint'] = ''; - } - - if ($weekday_name) { - $change_line['weekday_name'] = $weekday_name; - } else { - $change_line['weekday_name'] = ''; - } - - if ($start_time) { - $change_line['start_time'] = $start_time; - } else { - $change_line['start_time'] = ''; - } - - if ($meeting_borough) { - $change_line['location_city_subsection'] = $meeting_borough; - } else { - $change_line['location_city_subsection'] = ''; - } - - if ($meeting_town) { - $change_line['location_municipality'] = $meeting_town; - } else { - $change_line['location_municipality'] = ''; - } - - if ($meeting_state) { - $change_line['location_province'] = $meeting_state; - } else { - $change_line['location_province'] = ''; - } - - $ret .= '"'.implode('","', $change_line).'"'."\n"; - $ret = $this->TranslateCSVToXML($ret); - $ret = "\ngetMainURL()."client_interface/xsd/RestoreDeletedMeeting.php\">$ret"; - } else { - $ret = '

PROGRAM ERROR (MEETING FETCH FAILED)

'; - } - - return $ret; - } - - /********************************************************************************************************//** - \brief This is called to process the input and generate the output. It is the "heart" of the class. - - \returns XML to be returned. - ************************************************************************************************************/ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function process_commands() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $ret = null; - // We make sure that we are allowed to access this level of functionality. - // This is "belt and suspenders." We will constantly check user credentials. - if ($this->basic_user_validation()) { - if (isset($this->http_vars['admin_action']) && trim($this->http_vars['admin_action'])) { - set_time_limit(120); // Some requests can take a loooong time... - switch (strtolower(trim($this->http_vars['admin_action']))) { - case 'get_permissions': - $ret = $this->process_capabilities_request(); - break; - - case 'get_service_body_info': - $ret = $this->process_service_bodies_info_request(); - break; - - case 'get_format_info': - $ret = $this->process_format_info(); - break; - - case 'get_field_templates': - $ret = $this->process_get_field_templates(); - break; - - case 'get_meetings': - $ret = $this->process_meeting_search(); - break; - - case 'get_deleted_meetings': - $ret = $this->process_deleted_meetings(); - break; - - case 'get_changes': - $ret = $this->process_changes(); - break; - - case 'add_meeting': - $this->http_vars['meeting_id'] = 0; - unset($this->http_vars['meeting_id']); // Make sure that we have no meeting ID. This forces an add. - $ret = $this->process_meeting_modify(); - break; - - case 'rollback_meeting_to_before_change': - if (intval($this->http_vars['meeting_id']) && intval($this->http_vars['change_id'])) { // Make sure that we are referring to a meeting and a change. - $ret = $this->process_rollback_meeting(); - } else { - $ret = '

BAD ADMIN ACTION

'; - } - break; - - case 'restore_deleted_meeting': - if (intval($this->http_vars['meeting_id'])) { // Make sure that we are referring to a meeting - $ret = $this->process_restore_deleted_meeting(); - } else { - $ret = '

BAD ADMIN ACTION

'; - } - break; - - case 'modify_meeting': - if (intval($this->http_vars['meeting_id'])) { // Make sure that we are referring to a meeting. - $ret = $this->process_meeting_modify(); - } else { - $ret = '

BAD ADMIN ACTION

'; - } - break; - - case 'delete_meeting': - if (intval($this->http_vars['meeting_id'])) { // Make sure that we are referring to a meeting - $ret = $this->process_meeting_delete(); - } else { - $ret = '

BAD ADMIN ACTION

'; - } - break; - - case 'get_user_info': - $ret = $this->process_user_info(); - break; - - default: - $ret = '

BAD ADMIN ACTION

'; - break; - } - - set_time_limit(30); // Probably unnecessary... - } else { - $ret = '

BAD ADMIN ACTION

'; - } - } else { - $ret = '

NOT AUTHORIZED

'; - } - - return $ret; - } - - /********************************************************************************************************//** - \brief This is a basic funtion that tests the current user, to see if they are basically valid. - - \returns TRUE, if the user is valid. - ************************************************************************************************************/ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function basic_user_validation() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $ret = false; - - $user_obj = $this->server->GetCurrentUserObj(); - // First, make sure the use is of the correct general type. - if (isset($user_obj) && ($user_obj instanceof c_comdef_user) && ($user_obj->GetUserLevel() != _USER_LEVEL_DEACTIVATED) && ($user_obj->GetUserLevel() != _USER_LEVEL_SERVER_ADMIN) && ($user_obj->GetID() > 1)) { - $ret = true; - } - - return $ret; - } - - /********************************************************************************************************//** - \brief This fulfills a user request to get change records. - - \returns the XML for the change data. - ************************************************************************************************************/ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function process_changes() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $ret = '

NOT AUTHORIZED

'; - - // First, make sure the use is of the correct general type. - if ($this->basic_user_validation()) { - $start_date = (isset($this->http_vars['from_date']) && $this->http_vars['from_date']) ? strtotime($this->http_vars['from_date']) : (isset($this->http_vars['start_date']) && intval($this->http_vars['start_date']) ? intval($this->http_vars['start_date']) : null); - $end_date = (isset($this->http_vars['to_date']) && $this->http_vars['to_date']) ? strtotime($this->http_vars['to_date']) : (isset($this->http_vars['end_date']) && intval($this->http_vars['end_date']) ? intval($this->http_vars['end_date']) : null); - $meeting_id = isset($this->http_vars['meeting_id']) && intval($this->http_vars['meeting_id']) ? intval($this->http_vars['meeting_id']) : null; - $user_id = isset($this->http_vars['user_id']) && intval($this->http_vars['user_id']) ? intval($this->http_vars['user_id']) : null; - $service_body_id = null; - - if (isset($this->http_vars['service_body_id'])) { - $service_body_array = explode(",", $this->http_vars['service_body_id']); - - foreach ($service_body_array as $sb) { - $sb_int = intval($sb); - - if ($sb_int > 0) { - $sb_obj = c_comdef_server::GetServiceBodyByIDObj($sb_int); - - if ($sb_obj instanceof c_comdef_service_body) { - if ($sb_obj->UserCanObserve()) { - if (!isset($service_body_id)) { - $service_body_id = $sb_int; - } elseif (!is_array($service_body_id)) { - $service_body_id = array ( $service_body_id, $sb_int ); - } else { - $service_body_id[] = $sb_int; - } - } - } - } - } - } - - // We get the changes as CSV, then immediately turn them into XML. - $ret = $this->TranslateCSVToXML($this->get_changes_as_csv($start_date, $end_date, $meeting_id, $user_id, $service_body_id)); - $ret = "\ngetMainURL()."client_interface/xsd/GetChanges.php\">$ret"; - } - - return $ret; - } - - /********************************************************************************************************//** - \brief This fulfills a user request to restore a single deleted meeting. - - \returns the current meeting XML, if the rollback was successful. - ************************************************************************************************************/ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function process_rollback_meeting() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $ret = '

NOT AUTHORIZED

'; - - // First, make sure the user is of the correct general type. - if ($this->basic_user_validation()) { - $ret = '

PROGRAM ERROR (ROLLBACK FAILED)

'; - - $meeting_id = isset($this->http_vars['meeting_id']) && intval($this->http_vars['meeting_id']) ? intval($this->http_vars['meeting_id']) : null; - $change_id = isset($this->http_vars['change_id']) && intval($this->http_vars['change_id']) ? intval($this->http_vars['change_id']) : null; - - if ($meeting_id && $change_id) { - $change_objects = c_comdef_server::GetChangesFromIDAndType('c_comdef_meeting', $meeting_id); - - if ($change_objects instanceof c_comdef_changes) { - $obj_array = $change_objects->GetChangesObjects(); - - if (is_array($obj_array) && count($obj_array)) { - foreach ($obj_array as $change) { - if ($change->GetID() == $change_id) { - $beforeMeetingObject = $change->GetBeforeObject(); - if ($beforeMeetingObject) { - $currentMeetingObject = c_comdef_server::GetOneMeeting($meeting_id); - - if (($beforeMeetingObject instanceof c_comdef_meeting) && ($currentMeetingObject instanceof c_comdef_meeting)) { - if ($currentMeetingObject->UserCanEdit() && $beforeMeetingObject->UserCanEdit()) { - if ($change->Rollback()) { - $meeting_object = c_comdef_server::GetOneMeeting($meeting_id); - - $ret = $this->get_meeting_data($meeting_id); - } - } - } - } - - break; - } - } - } - } - } - } - - return $ret; - } - - /********************************************************************************************************//** - \brief This fulfills a user request to restore a single deleted meeting. - - \returns the XML for the meeting data. - ************************************************************************************************************/ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function process_restore_deleted_meeting() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $ret = ''; - - // First, make sure the user is of the correct general type. - if ($this->basic_user_validation()) { - $meeting_id = isset($this->http_vars['meeting_id']) && intval($this->http_vars['meeting_id']) ? intval($this->http_vars['meeting_id']) : null; - - if ($meeting_id) { - $change_objects = c_comdef_server::GetChangesFromIDAndType('c_comdef_meeting', $meeting_id); - - if ($change_objects instanceof c_comdef_changes) { - $obj_array = $change_objects->GetChangesObjects(); - - if (is_array($obj_array) && count($obj_array)) { - foreach ($obj_array as $change) { - if ($change instanceof c_comdef_change) { - if ($change->GetAfterObject()) { - continue; - } - - $unrestored_meeting_object = $change->GetBeforeObject(); - - if ($unrestored_meeting_object->UserCanEdit()) { - $unrestored_meeting_object->SetPublished(false); // Newly restored meetings are always unpublished. - $unrestored_meeting_object->UpdateToDB(); - $ret = $this->get_meeting_data($meeting_id); - } else { - $ret = '

NOT AUTHORIZED

'; - } - } else { - $ret = '

PROGRAM ERROR (NO VALID CHANGE RECORD)

'; - } - } - } else { - $ret = '

NO MEETING AVAILABLE

'; - } - } else { - $ret = '

NO MEETING AVAILABLE

'; - } - } else { - $ret = '

NO MEETING SPECIFIED

'; - } - } else { - $ret = '

NOT AUTHORIZED

'; - } - - - return $ret; - } - - /********************************************************************************************************//** - \brief This fulfills a user request to delete a meeting. - - \returns the XML for the meeting data. - ************************************************************************************************************/ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function process_deleted_meetings() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $ret = ''; - - // First, make sure the user is of the correct general type. - if ($this->basic_user_validation()) { - $start_date = (isset($this->http_vars['from_date']) && $this->http_vars['from_date']) ? strtotime($this->http_vars['from_date']) : (isset($this->http_vars['start_date']) && intval($this->http_vars['start_date']) ? intval($this->http_vars['start_date']) : null); - $end_date = (isset($this->http_vars['to_date']) && $this->http_vars['to_date']) ? strtotime($this->http_vars['to_date']) : (isset($this->http_vars['end_date']) && intval($this->http_vars['end_date']) ? intval($this->http_vars['end_date']) : null); - $meeting_id = isset($this->http_vars['meeting_id']) && intval($this->http_vars['meeting_id']) ? intval($this->http_vars['meeting_id']) : null; - $user_id = isset($this->http_vars['user_id']) && intval($this->http_vars['user_id']) ? intval($this->http_vars['user_id']) : null; - $service_body_id = null; - - if (isset($this->http_vars['service_body_id'])) { - $service_body_array = explode(",", $this->http_vars['service_body_id']); - - foreach ($service_body_array as $sb) { - $sb_int = intval($sb); - - if ($sb_int > 0) { - $sb_obj = c_comdef_server::GetServiceBodyByIDObj($sb_int); - - if ($sb_obj instanceof c_comdef_service_body) { - if ($sb_obj->UserCanObserve()) { - if (!isset($service_body_id)) { - $service_body_id = $sb_int; - } elseif (!is_array($service_body_id)) { - $service_body_id = array ( $service_body_id, $sb_int ); - } else { - $service_body_id[] = $sb_int; - } - } - } - } - } - } - - // We get the deleted meetings as CSV, then immediately turn them into XML. - $ret = $this->get_deleted_meetings_as_csv($start_date, $end_date, $meeting_id, $user_id, $service_body_id); - $ret = $this->TranslateCSVToXML($ret); - $ret = "\ngetMainURL()."client_interface/xsd/GetDeletedMeetings.php\">$ret"; - } else { - $ret = '

NOT AUTHORIZED

'; - } - - return $ret; - } - - /*******************************************************************/ - /** - \brief This returns deleted meeting records in CSV form (which we turn into XML). - - \returns CSV data, with the first row a key header. - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function get_deleted_meetings_as_csv( - $in_start_date = null, ///< Optional. A start date (In PHP time() format). If supplied, then only deletions on, or after this date will be returned. - $in_end_date = null, ///< Optional. An end date (In PHP time() format). If supplied, then only deletions that occurred on, or before this date will be returned. - $in_meeting_id = null, ///< Optional. If supplied, an ID for a particular meeting. Only deletion for that meeting will be returned. - $in_user_id = null, ///< Optional. If supplied, an ID for a particular user. Only deletions made by that user will be returned. - $in_sb_id = null ///< Optional. If supplied, an ID for a particular Service body. Only deletions for meetings in that Service body will be returned. If this is an array, then multiple Service bodies will be searched. - ) { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $ret = null; - try { - $change_objects = c_comdef_server::GetChangesFromIDAndType('c_comdef_meeting', null, $in_start_date, $in_end_date); - if ($change_objects instanceof c_comdef_changes) { - $obj_array = $change_objects->GetChangesObjects(); - - if (is_array($obj_array) && count($obj_array)) { - set_time_limit(max(30, intval(count($obj_array) / 20))); // Change requests can take a loooong time... - $localized_strings = c_comdef_server::GetLocalStrings(); - require_once(dirname(dirname(dirname(__FILE__))).'/server/config/get-config.php'); - // These are our columns. This will be our header line. - $ret = '"deletion_date_int","deletion_date_string","user_id","user_name","service_body_id","service_body_name","meeting_id","meeting_name","weekday_tinyint","weekday_name","start_time","location_city_subsection","location_municipality","location_province"'."\n"; - - // If they specify a Service body, we also look in "child" Service bodies, so we need to produce a flat array of IDs. - if (isset($in_sb_id) && $in_sb_id) { - // If this is not an array, then we check for children. If it is an array, then we just do exactly what is in the array, regardless of children. - if (!is_array($in_sb_id) || !count($in_sb_id)) { - global $bmlt_array_gather; - - $bmlt_array_gather = array(); - - /************************************************//** - * This little internal function will simply fill * - * the $bmlt_array_gather array with a linear set of * - * Service body IDs that can be used for a quick * - * comparison, later on. It is a callback function. * - ****************************************************/ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - function bmlt_at_at( - $in_value, - $in_key - ) { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - global $bmlt_array_gather; - - if ($in_value instanceof c_comdef_service_body) { - array_push($bmlt_array_gather, $in_value->GetID()); - } - } - - $array_to_walk = c_comdef_server::GetServer()->GetNestedServiceBodyArray($in_sb_id); - array_walk_recursive($array_to_walk, 'bmlt_at_at'); - - if (is_array($bmlt_array_gather) && count($bmlt_array_gather)) { - $in_sb_id = $bmlt_array_gather; - } else { - $in_sb_id = array ( $in_sb_id ); - } - } - } - - $fetched_ids_array = array(); - - foreach ($obj_array as $change) { - $date_int = intval($change->GetChangeDate()); - $date_string = date("Y-m-d H:m:s", $date_int); - - if ($change instanceof c_comdef_change) { - $b_obj = $change->GetBeforeObject(); - - if ($change->GetAfterObject()) { // We are only interested in deleted meetings. If After exists, it was not a deletion. - continue; - } - - $meeting_id = intval($change->GetBeforeObjectID()); // By default, we get the meeting ID from the "before" object. - $sb_b = intval(($b_obj instanceof c_comdef_meeting) ? $b_obj->GetServiceBodyID() : 0); - - $sb_obj = c_comdef_server::GetServiceBodyByIDObj($sb_b); - if (($sb_obj instanceof c_comdef_service_body) && $sb_obj->UserCanObserve()) { - $sb_c = intval($change->GetServiceBodyID()); - - if (in_array($meeting_id, $fetched_ids_array)) { - continue; - } - - // If this meeting currently exists, then it doesn't qualify. - if (c_comdef_server::GetMeetingsByID(array ( $meeting_id ))) { - continue; - } - - $fetched_ids_array[] = $meeting_id; - - // If we are looking for a particular meeting, and this is it, or we don't care, then go ahead. - if ((intval($in_meeting_id) && intval($in_meeting_id) == intval($meeting_id)) || !intval($in_meeting_id)) { - $meeting_name = ''; - $user_name = ''; - $meeting_town = ''; - $meeting_state = ''; - - // If we are looking for a particular Service body, and this is it, or we don't caer about the Service body, then go ahead. - if (!is_array($in_sb_id) || !count($in_sb_id) || in_array($sb_b, $in_sb_id) || in_array($sb_c, $in_sb_id)) { - $sb_id = (intval($sb_c) ? $sb_c : $sb_b); - - $user_id = intval($change->GetUserID()); - - // If the user was specified, we look for changes by that user only. Otherwise, we don't care. - if ((isset($in_user_id) && $in_user_id && ($in_user_id == $user_id)) || !isset($in_user_id) || !$in_user_id) { - // Get the user that created this change. - $user = c_comdef_server::GetUserByIDObj($user_id); - - if ($user instanceof c_comdef_user) { - $user_name = $user->GetLocalName(); - } else { - $user_name = '????'; // Otherwise, it's a mystery. - } - - // Using str_replace, because preg_replace is pretty expensive. However, I don't think this buys us much. - if ($b_obj instanceof c_comdef_meeting) { - $meeting_name = str_replace('"', "'", str_replace("\n", " ", str_replace("\r", " ", $b_obj->GetMeetingDataValue('meeting_name')))); - $meeting_borough = str_replace('"', "'", str_replace("\n", " ", str_replace("\r", " ", $b_obj->GetMeetingDataValue('location_city_subsection')))); - $meeting_town = str_replace('"', "'", str_replace("\n", " ", str_replace("\r", " ", $b_obj->GetMeetingDataValue('location_municipality')))); - $meeting_state = str_replace('"', "'", str_replace("\n", " ", str_replace("\r", " ", $b_obj->GetMeetingDataValue('location_province')))); - } - - $weekday_tinyint = intval($b_obj->GetMeetingDataValue('weekday_tinyint')); - $weekday_name = $localized_strings["comdef_server_admin_strings"]["meeting_search_weekdays_names"][$weekday_tinyint]; - - $start_time = $b_obj->GetMeetingDataValue('start_time'); - - $sb = c_comdef_server::GetServiceBodyByIDObj($sb_id); - - if ($sb instanceof c_comdef_service_body) { - $sb_name = $sb->GetLocalName(); - } else { - $sb_name = '????'; - } - - // We create an array, which we'll implode after we're done. Easy way to create a CSV row. - $change_line = array(); - - // Create each column for this row. - if ($date_int) { - $change_line['deletion_date_int'] = $date_int; - } else { - $change_line['deletion_date_int'] = 0; - } - - if ($date_string) { - $change_line['deletion_date_string'] = $date_string; - } else { - $change_line['deletion_date_string'] = ''; - } - - if ($user_id) { - $change_line['user_id'] = $user_id; - } else { - $change_line['user_id'] = 0; - } - - if ($user_name) { - $change_line['user_name'] = $user_name; - } else { - $change_line['user_name'] = ''; - } - - if ($sb_id) { - $change_line['service_body_id'] = $sb_id; - } else { - $change_line['service_body_id'] = ''; - } - - if ($sb_name) { - $change_line['service_body_name'] = $sb_name; - } else { - $change_line['service_body_name'] = ''; - } - - if ($meeting_id) { - $change_line['meeting_id'] = $meeting_id; - } else { - $change_line['meeting_id'] = 0; - } - - if ($meeting_name) { - $change_line['meeting_name'] = $meeting_name; - } else { - $change_line['meeting_name'] = ''; - } - - if ($weekday_tinyint) { - $change_line['weekday_tinyint'] = $weekday_tinyint; - } else { - $change_line['weekday_tinyint'] = ''; - } - - if ($weekday_name) { - $change_line['weekday_name'] = $weekday_name; - } else { - $change_line['weekday_name'] = ''; - } - - if ($start_time) { - $change_line['start_time'] = $start_time; - } else { - $change_line['start_time'] = ''; - } - - if ($meeting_borough) { - $change_line['location_city_subsection'] = $meeting_borough; - } else { - $change_line['location_city_subsection'] = ''; - } - - if ($meeting_town) { - $change_line['location_municipality'] = $meeting_town; - } else { - $change_line['location_municipality'] = ''; - } - - if ($meeting_state) { - $change_line['location_province'] = $meeting_state; - } else { - $change_line['location_province'] = ''; - } - - $ret .= '"'.implode('","', $change_line).'"'."\n"; - } - } - } - } - } - } - } - } - } catch (Exception $e) { - $ret = '

ERROR

'; - } - - return $ret; - } - - /*******************************************************************/ - /** - \brief This returns change records in CSV form (which we turn into XML). - - \returns CSV data, with the first row a key header. - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function get_changes_as_csv( - $in_start_date = null, ///< Optional. A start date (In PHP time() format). If supplied, then only changes on, or after this date will be returned. - $in_end_date = null, ///< Optional. An end date (In PHP time() format). If supplied, then only changes that occurred on, or before this date will be returned. - $in_meeting_id = null, ///< Optional. If supplied, an ID for a particular meeting. Only changes for that meeting will be returned. - $in_user_id = null, ///< Optional. If supplied, an ID for a particular user. Only changes made by that user will be returned. - $in_sb_id = null, ///< Optional. If supplied, an ID for a particular Service body. Only changes for that Service body will be returned. - $in_change_type = 'c_comdef_meeting' ///< This is the change type. Default is meeting change (NOTE: This function needs work to handle other types, but I figured I'd put in a hook for later). - ) { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $ret = null; - try { - // Start by getting every meeting change between the given dates. - $change_objects = c_comdef_server::GetChangesFromIDAndType($in_change_type, null, $in_start_date, $in_end_date); - if ($change_objects instanceof c_comdef_changes) { - $obj_array = $change_objects->GetChangesObjects(); - - if (is_array($obj_array) && count($obj_array)) { - set_time_limit(max(30, intval(count($obj_array) / 20))); // Change requests can take a loooong time... - $localized_strings = c_comdef_server::GetLocalStrings(); - require_once(dirname(dirname(dirname(__FILE__))).'/server/config/get-config.php'); - // These are our columns. This will be our header line. - $ret = '"new_meeting","change_id","date_int","date_string","change_type","meeting_id","meeting_name","user_id","user_name","service_body_id","service_body_name","meeting_exists","details"'."\n"; - - // If they specify a Service body, we also look in "child" Service bodies, so we need to produce a flat array of IDs. - if (isset($in_sb_id) && $in_sb_id) { - // If this is not an array, then we check for children. If it is an array, then we just do exactly what is in the array, regardless of children. - if (!is_array($in_sb_id) || !count($in_sb_id)) { - global $bmlt_array_gather; - - $bmlt_array_gather = array(); - - /************************************************//** - * This little internal function will simply fill * - * the $bmlt_array_gather array with a linear set of * - * Service body IDs that can be used for a quick * - * comparison, later on. It is a callback function. * - ****************************************************/ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - function bmlt_at_at( - $in_value, - $in_key - ) { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - global $bmlt_array_gather; - - if ($in_value instanceof c_comdef_service_body) { - array_push($bmlt_array_gather, $in_value->GetID()); - } - } - - $array_to_walk = c_comdef_server::GetServer()->GetNestedServiceBodyArray($in_sb_id); - array_walk_recursive($array_to_walk, 'bmlt_at_at'); - - if (is_array($bmlt_array_gather) && count($bmlt_array_gather)) { - $in_sb_id = $bmlt_array_gather; - } else { - $in_sb_id = array ( $in_sb_id ); - } - } - } - - foreach ($obj_array as $change) { - $change_type = $change->GetChangeType(); - $date_int = intval($change->GetChangeDate()); - $date_string = date("Y-m-d H:m:s", $date_int); - - if ($change instanceof c_comdef_change) { - $b_obj = $change->GetBeforeObject(); - $a_obj = $change->GetAfterObject(); - $meeting_id = intval($change->GetBeforeObjectID()); // By default, we get the meeting ID from the "before" object. - $sb_a = intval(($a_obj instanceof c_comdef_meeting) ? $a_obj->GetServiceBodyID() : 0); - $sb_b = intval(($b_obj instanceof c_comdef_meeting) ? $b_obj->GetServiceBodyID() : 0); - $sb_c = intval($change->GetServiceBodyID()); - - // If the meeting was newly created, then we get the ID from the "after" object. - if (!$meeting_id) { - $meeting_id = intval($change->GetAfterObjectID()); - } - - // If we are looking for a particular meeting, and this is it, or we don't care, then go ahead. - if ((intval($in_meeting_id) && intval($in_meeting_id) == intval($meeting_id)) || !intval($in_meeting_id)) { - $meeting_name = ''; - $user_name = ''; - - // If we are looking for a particular Service body, and this is it, or we don't caer about the Service body, then go ahead. - if (!is_array($in_sb_id) || !count($in_sb_id) || in_array($sb_a, $in_sb_id) || in_array($sb_b, $in_sb_id) || in_array($sb_c, $in_sb_id)) { - $sb_id = (intval($sb_c) ? $sb_c : (intval($sb_b) ? $sb_b : $sb_a)); - - $user_id = intval($change->GetUserID()); - - // If the user was specified, we look for changes by that user only. Otherwise, we don't care. - if ((isset($in_user_id) && $in_user_id && ($in_user_id == $user_id)) || !isset($in_user_id) || !$in_user_id) { - // Get the user that created this change. - $user = c_comdef_server::GetUserByIDObj($user_id); - - if ($user instanceof c_comdef_user) { - $user_name = $user->GetLocalName(); - } else { - $user_name = '????'; // Otherwise, it's a mystery. - } - - // Using str_replace, because preg_replace is pretty expensive. However, I don't think this buys us much. - if ($b_obj instanceof c_comdef_meeting) { - $meeting_name = str_replace('"', "'", str_replace("\n", " ", str_replace("\r", " ", $b_obj->GetMeetingDataValue('meeting_name')))); - } elseif ($a_obj instanceof c_comdef_meeting) { - $meeting_name = str_replace('"', "'", str_replace("\n", " ", str_replace("\r", " ", $a_obj->GetMeetingDataValue('meeting_name')))); - } - - $sb = c_comdef_server::GetServiceBodyByIDObj($sb_id); - - if ($sb instanceof c_comdef_service_body) { - $sb_name = $sb->GetLocalName(); - } else { - $sb_name = '????'; - } - - // We see if the meeting currently exists. - $meeting_exists = 0; - - if (c_comdef_server::GetOneMeeting($meeting_id, true)) { - $meeting_exists = 1; - } - - // Get the details of the change. - $details = ''; - $desc = $change->DetailedChangeDescription(); - - if ($desc && isset($desc['details']) && is_array($desc['details'])) { - // We need to prevent double-quotes, as they are the string delimiters, so we replace them with single-quotes. - $details = htmlspecialchars_decode(str_replace('"', "'", str_replace("\n", " ", str_replace("\r", " ", implode(" ", $desc['details'])))), ENT_COMPAT); - } elseif ($desc && isset($desc['details'])) { - // We need to prevent double-quotes, as they are the string delimiters, so we replace them with single-quotes. - $details = htmlspecialchars_decode(str_replace('"', "'", str_replace("\n", " ", str_replace("\r", " ", $desc['details']))), ENT_COMPAT); - } else { - $details = htmlspecialchars_decode(str_replace('"', "'", str_replace("\n", " ", str_replace("\r", " ", $desc['overall']))), ENT_COMPAT); - } - - // We create an array, which we'll implode after we're done. Easy way to create a CSV row. - $change_line = array(); - - // Create each column for this row. - $change_line["new_meeting"] = ($b_obj instanceof c_comdef_meeting) ? 0 : 1; - - $change_line['change_id'] = $change->GetID(); - - if ($date_int) { - $change_line['date_int'] = $date_int; - } else { - $change_line['date_int'] = 0; - } - - if ($date_string) { - $change_line['date_string'] = $date_string; - } else { - $change_line['date_string'] = ''; - } - - if ($change_type) { - $change_line['change_type'] = $change_type; - } else { - $change_line['change_type'] = ''; - } - - if ($meeting_id) { - $change_line['meeting_id'] = $meeting_id; - } else { - $change_line['meeting_id'] = 0; - } - - if ($meeting_name) { - $change_line['meeting_name'] = $meeting_name; - } else { - $change_line['meeting_name'] = ''; - } - - if ($user_id) { - $change_line['user_id'] = $user_id; - } else { - $change_line['user_id'] = 0; - } - - if ($user_name) { - $change_line['user_name'] = $user_name; - } else { - $change_line['user_name'] = ''; - } - - if ($sb_id) { - $change_line['service_body_id'] = $sb_id; - } else { - $change_line['service_body_id'] = ''; - } - - if ($sb_name) { - $change_line['service_body_name'] = $sb_name; - } else { - $change_line['service_body_name'] = ''; - } - - $change_line['meeting_exists'] = $meeting_exists; - - if ($details) { - $change_line['details'] = $details; - } else { - $change_line['details'] = ''; - } - - $ret .= '"'.implode('","', $change_line).'"'."\n"; - } - } - } - } - } - } - } - } catch (Exception $e) { - $ret = '

ERROR

'; - } - - return $ret; - } - - /********************************************************************************************************//** - \brief This fulfills a user request to get all the available fields for adding/modifying meeting data. - - \returns the XML for the template data. - ************************************************************************************************************/ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function process_get_field_templates() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $ret = ''; - - // First, make sure the use is of the correct general type. - if ($this->basic_user_validation()) { - // Get the template data from the database. - $template_data = array_merge(c_comdef_meeting::GetMainDataTemplate(), c_comdef_meeting::GetDataTableTemplate()); - $template_longdata = c_comdef_meeting::GetLongDataTableTemplate(); - - // We merge the two tables (data and longdata). - if (is_array($template_data) && count($template_data) && is_array($template_longdata) && count($template_longdata)) { - $template_data = array_merge($template_data, $template_longdata); - } - - // $template_data now contains the templates for the meeting data. These are the available "slots" for new values. We need to convert to XML. - - foreach ($template_data as $template) { - $ret .= ''; - $ret .= ''.c_comdef_htmlspecialchars($template['key']).''; - $ret .= ''.c_comdef_htmlspecialchars($template['field_prompt']).''; - $ret .= ''.c_comdef_htmlspecialchars($template['lang_enum']).''; - $ret .= ''.intval($template['visibility']).''; - - if (isset($template['data_string'])) { - $ret .= ''.c_comdef_htmlspecialchars($template['data_string']).''; - } - - if (isset($template['data_bigint'])) { - $ret .= ''.intval($template['data_bigint']).''; - } - - if (isset($template['data_double'])) { - $ret .= ''.intval($template['data_double']).''; - } - - if (isset($template['data_longtext'])) { - $ret .= ''.c_comdef_htmlspecialchars($template['data_longtext']).''; - } - - if (isset($template['data_blob'])) { - $ret .= ''.c_comdef_htmlspecialchars(base64_encode($template['data_blob'])).''; - } - $ret .= ''; - } - - $ret = "\ngetMainURL()."client_interface/xsd/FieldTemplates.php\">$ret"; - } else { - $ret = '

NOT AUTHORIZED

'; - } - - return $ret; - } - - /********************************************************************************************************//** - \brief This fulfills a user request to delete an existing meeting. $this->http_vars['meeting_id'] must be set to the meeting ID. - - \returns A very simple XML Report. - ************************************************************************************************************/ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function process_meeting_delete() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $ret = null; - - // First, make sure the use is of the correct general type. - if ($this->basic_user_validation()) { - $meeting_obj = $this->server->GetOneMeeting(intval($this->http_vars['meeting_id'])); - if ($meeting_obj instanceof c_comdef_meeting) { // Make sure we got a meeting. - if ($meeting_obj->UserCanEdit($this->server->GetCurrentUserObj())) { // Make sure that we are allowed to edit this meeting. - // Before we say goodbye, we take down the relevant details for the next of kin... - $id = intval($meeting_obj->GetID()); - $service_body_id = intval($meeting_obj->GetServiceBodyID()); - $name = c_comdef_htmlspecialchars(str_replace('"', "'", str_replace("\n", " ", str_replace("\r", " ", $meeting_obj->GetMeetingDataValue('meeting_name'))))); - $weekday = intval($meeting_obj->GetMeetingDataValue('weekday_tinyint')); - $start_time = c_comdef_htmlspecialchars($meeting_obj->GetMeetingDataValue('start_time')); - - $meeting_obj->DeleteFromDB(); // Delete the meeting. - - // Write out the death certificate. - $ret = ''.$id.''.$id.''.$name.''.$service_body_id.''.$start_time.''.$weekday.''; - $ret = "\ngetMainURL()."client_interface/xsd/DeletedMeeting.php\" id=\"$id\">$ret"; - } else { - $ret = '

NOT AUTHORIZED

'; - } - } else { - $ret = '

ERROR

'; - } - } else { - $ret = '

NOT AUTHORIZED

'; - } - - return $ret; - } - - /********************************************************************************************************//** - \brief This fulfills a user request to modify fields in a meeting (or create a new meeting). - This requires that the following HTTP parameters be set: - - meeting_id This is an integer that is the BMLT ID of the meeting being modified (the user must have edit rights to this meeting). If this is 0 (or unset), then we will be creating a new meeting. - If we are creating a new meeting, the new meeting will start at 8:30PM on Sunday, unless new values for the 'weekday' and 'start_time' fields are provided. - Once the meeting is created, we can set any of its fields as given. - - meeting_field This is a string, or array of string, with the field name in the meeting search response. - - new_value This is a string, or array of string, with the new value for the field. If the meeting_field parameter is an array, then each value here needs to be specified to correspond with the field. - - \returns XML, containing the fields modified. - ************************************************************************************************************/ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function process_meeting_modify() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $ret = null; - - $user_obj = $this->server->GetCurrentUserObj(); - // First, make sure the use is of the correct general type. - if ($this->basic_user_validation()) { - $closing_tag = ''; // We will usually be changing existing meetings. - $my_editable_service_bodies = array(); - $thisIsANewMeeting = false; // Set to true for new meetings. - - $service_bodies = $this->server->GetServiceBodyArray(); - - if ($user_obj->GetUserLevel() == _USER_LEVEL_SERVICE_BODY_ADMIN) { // Must be a Service Body Admin. - // We cycle through all the Service bodies, and look for ones in which we have permissions. - // We use the Service body IDs to key them in associative arrays. - foreach ($service_bodies as $service_body) { - if ($service_body->UserCanEditMeetings()) { // We are a full Service body editor, with rights to edit the Service body itself (as well as all its meetings). - $my_editable_service_bodies['sb_'.$service_body->GetID()] = $service_body; - } - } - } - - $new_meeting_id = 0; - // Get the meeting object, itself. - if (!intval($this->http_vars['meeting_id'])) { // Will we be creating a new meeting? - $service_bodies = $this->server->GetServiceBodyArray(); - - if ($user_obj->GetUserLevel() == _USER_LEVEL_SERVICE_BODY_ADMIN) { // Must be a Service Body Admin. - if (isset($my_editable_service_bodies) && is_array($my_editable_service_bodies) && count($my_editable_service_bodies)) { - $service_body_id = 0; - - // If we are allowed to edit more than one Service body, then we are given a choice. We must supply an ID for the new meeting. - if (count($my_editable_service_bodies) > 1) { - if (isset($this->http_vars['service_body_id']) && intval($this->http_vars['service_body_id'])) { - $service_body_id = intval($this->http_vars['service_body_id']); - } else { - $meeting_fields = $this->http_vars['meeting_field']; - - foreach ($meeting_fields as $field) { - list ( $key, $value ) = explode(',', $field); - - if ($key == 'service_body_bigint') { - $service_body_id = intval($value); - break; - } - } - } - } else // Otherwise, it is picked for us. - { - // We have to do this odd dance, because it's an associative array. - $keys_1 = array_keys($my_editable_service_bodies); - - $service_body = $my_editable_service_bodies[$keys_1[0]]; - - if ($service_body instanceof c_comdef_service_body) { - $service_body_id = $service_body->GetID(); - } - } - - $weekday = 1; // Default is Sunday - $start_time = '20:30:00'; // Default is 8:30 PM - $lang = c_comdef_server::GetServer()->GetLocalLang(); // We use whatever the server language is. - if ($service_body_id) { // Can't create a new meeting without a Service body. - $service_body = c_comdef_server::GetServer()->GetServiceBodyByIDObj($service_body_id); - - if ($service_body instanceof c_comdef_service_body) { - if ($service_body->UserCanEditMeetings($user_obj)) { - $new_meeting_id = c_comdef_server::AddNewMeeting($service_body_id, $weekday, $start_time, $lang); - $meeting_obj = $this->server->GetOneMeeting(intval($new_meeting_id)); - $meeting_obj->SetPublished(false); // New meetings are always unpublished. - $meeting_id = $new_meeting_id; - $ret = ''; - $thisIsANewMeeting = true; - $closing_tag = ''; - } else { - $ret = '

NOT AUTHORIZED

'; - } - } else { - $ret = '

ERROR

'; - } - } else { - $ret = '

ERROR

'; - } - } else { - $ret = '

NOT AUTHORIZED

'; - } - } else { - $ret = '

NOT AUTHORIZED

'; - } - } else { - $meeting_obj = $this->server->GetOneMeeting(intval($this->http_vars['meeting_id'])); - $ret = ''; - } - - if ($meeting_obj instanceof c_comdef_meeting) { - if ($meeting_obj->UserCanEdit($user_obj)) { // We next make sure that we are allowed to make changes to this meeting. - $keys = c_comdef_meeting::GetAllMeetingKeys(); // Get all the available keys. The one passed in needs to match one of these. - $localized_strings = c_comdef_server::GetLocalStrings(); - - // In case we need to add a new field, we get the meeting data template. - $template_data = c_comdef_meeting::GetDataTableTemplate(); - $template_longdata = c_comdef_meeting::GetLongDataTableTemplate(); - - // We merge the two tables (data and longdata). - if (is_array($template_data) && count($template_data) && is_array($template_longdata) && count($template_longdata)) { - $template_data = array_merge($template_data, $template_longdata); - } - - // If so, we take the field, and tweak its value. - $meeting_fields = $this->http_vars['meeting_field']; - - if (!is_array($meeting_fields)) { - $meeting_fields = array ( $meeting_fields ); - } - - // We change each of the fields passed in to the new values passed in. - foreach ($meeting_fields as $field) { - list ( $meeting_field, $value ) = explode(',', $field, 2); - if (strpos($value, "##-##")) { // Look for our special flagged items. - $temp = explode("##-##", $value); - $value = $temp[count($temp) - 1]; - } - - if (isset($meeting_field) && in_array($meeting_field, $keys)) { - switch ($meeting_field) { - case 'id_bigint': // We don't currently let these get changed. - case 'lang_enum': - $value = null; - $old_value = null; - break; - - case 'service_body_bigint': - if (isset($my_editable_service_bodies) && is_array($my_editable_service_bodies) && count($my_editable_service_bodies)) { - $before_id = intval($meeting_obj->GetServiceBodyID()); - $after_id = intval($value); - - // Have to be allowed to edit both. - if ($my_editable_service_bodies['sb_'.$before_id] && $my_editable_service_bodies['sb_'.$after_id]) { - $old_value = $meeting_obj->GetServiceBodyID(); - $meeting_obj->SetServiceBodyID(intval($value)); - } else { - $ret = '

NOT AUTHORIZED

'; - } - } else { - $ret = '

NOT AUTHORIZED

'; - } - break; - - case 'email_contact': - $old_value = $meeting_obj->GetEmailContact(); - $meeting_obj->SetEmailContact(intval($value)); - break; - - case 'published': - if (!$new_meeting_id) { // New meetings are always unpublished. - $old_value = $meeting_obj->IsPublished(); - $meeting_obj->SetPublished(intval($value) != 0 ? true : false); - } else { - $old_value = 0; - $value = 0; - } - break; - - case 'weekday_tinyint': - if ((intval($value) > 0) && (intval($value) < 8)) { - $old_value = $meeting_obj->GetMeetingDataValue($meeting_field); - $data =& $meeting_obj->GetMeetingData(); - $data[$meeting_field] = intval($value); - } - break; - - case 'longitude': - case 'latitude': - if (floatval($value) != 0.0) { - $old_value = $meeting_obj->GetMeetingDataValue($meeting_field); - $data =& $meeting_obj->GetMeetingData(); - $data[$meeting_field] = floatval($value); - } - break; - - case 'start_time': - case 'duration_time': - case 'time_zone': - $old_value = $meeting_obj->GetMeetingDataValue($meeting_field); - $data =& $meeting_obj->GetMeetingData(); - $data[$meeting_field] = $value; - break; - - case 'formats': - // Formats take some extra work, because we store them in the meeting as individual objects, so we create, sort and apply those objects. - $old_value_array = $meeting_obj->GetMeetingDataValue($meeting_field); - $lang = $this->server->GetLocalLang(); - $vals = array(); - - foreach ($old_value_array as $format) { - if ($format) { - $vals[$format->GetSharedID()] = $format; - } - } - - uksort($vals, array ( 'c_comdef_meeting','format_sorter_simple' )); - - $keys_2 = array(); - foreach ($vals as $format) { - $keys_2[] = $format->GetKey(); - } - - $old_value = implode(",", $keys_2); - - $formats = explode(",", $value); - $formats_object = $this->server->GetFormatsObj(); - - $newVals = array(); - foreach ($formats as $key) { - $object = $formats_object->GetFormatByKeyAndLanguage($key, $lang); - if ($object instanceof c_comdef_format) { - $newVals[$object->GetSharedID()] = $object; - } - } - - uksort($newVals, array ( 'c_comdef_meeting','format_sorter_simple' )); - $data =& $meeting_obj->GetMeetingData(); - $data[$meeting_field] = $newVals; - break; - - case 'worldid_mixed': - $old_value = $meeting_obj->GetMeetingDataValue($meeting_field); - $data =& $meeting_obj->GetMeetingData(); - $data[$meeting_field] = $value; - break; - - case 'meeting_name': - $old_value = $meeting_obj->GetMeetingDataValue($meeting_field); - if (!isset($value) || !$value) { - $value = $localized_strings["comdef_server_admin_strings"]["Value_Prompts"]["generic"]; - } - // Assuming fallthrough is intentional here, due to lack of break statement? - - default: - $old_value = $meeting_obj->GetMeetingDataValue($meeting_field); - $data =& $meeting_obj->GetMeetingData(); - $prompt = isset($data[$meeting_field]['field_prompt']) ? $data[$meeting_field]['field_prompt'] : $template_data[$meeting_field]['field_prompt']; - $visibility = intval(isset($data[$meeting_field]['visibility']) ? $data[$meeting_field]['visibility'] : $template_data[$meeting_field]['visibility']); - $meeting_obj->AddDataField($meeting_field, $prompt, $value, null, $visibility, true); - break; - } - - // We only indicate changes. - if (isset($meeting_field) && $meeting_field && !($thisIsANewMeeting && !(isset($value) && $value)) && ((isset($old_value) && $old_value) || (isset($value) && $value)) && ($old_value != $value)) { - $ret_temp = ''; - $ret_temp_internal = ''; - // New meetings have no old data. - if (!$thisIsANewMeeting && isset($old_value) && $old_value) { - $ret_temp_internal .= ''.c_comdef_htmlspecialchars($old_value).''; - } - - if (isset($value) && $value) { - $ret_temp_internal .= ''.c_comdef_htmlspecialchars($value).''; - } - - $ret_temp .= ''.$ret_temp_internal.''; - - // We only send back changes that were actually made. This reduces empty response data. - if ($ret_temp_internal) { - $ret .= $ret_temp; - } - } - - $meeting_field = null; - } - } - - // This can short-circuit the operation. - if ($ret != '

NOT AUTHORIZED

') { - $meeting_obj->UpdateToDB(); // Save the new data. After this, the meeting has been changed. - - $ret .= $closing_tag; - - $ret = "\ngetMainURL()."client_interface/xsd/ChangeResponse.php\">$ret"; - } - } else { - $ret = '

NOT AUTHORIZED

'; - } - } else { - $ret = '

ERROR

'; - } - } else { - $ret = '

NOT AUTHORIZED

'; - } - - return $ret; - } - - /********************************************************************************************************//** - \brief This fulfills a user request to return meeting information from a search. - - \returns XML, containing the answer. - ************************************************************************************************************/ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function process_meeting_search() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - if (!( isset($this->http_vars['geo_width']) && $this->http_vars['geo_width'] ) && isset($this->http_vars['bmlt_search_type']) && ($this->http_vars['bmlt_search_type'] == 'advanced') && isset($this->http_vars['advanced_radius']) && isset($this->http_vars['advanced_mapmode']) && $this->http_vars['advanced_mapmode'] && ( floatval($this->http_vars['advanced_radius'] != 0.0) ) && isset($this->http_vars['lat_val']) && isset($this->http_vars['long_val']) && ( (floatval($this->http_vars['lat_val']) != 0.0) || (floatval($this->http_vars['long_val']) != 0.0) )) { - $this->http_vars['geo_width'] = $this->http_vars['advanced_radius']; - } elseif (!( isset($this->http_vars['geo_width']) && $this->http_vars['geo_width'] ) && isset($this->http_vars['bmlt_search_type']) && ($this->http_vars['bmlt_search_type'] == 'advanced')) { - $this->http_vars['lat_val'] = null; - $this->http_vars['long_val'] = null; - } elseif (!isset($this->http_vars['geo_loc']) || $this->http_vars['geo_loc'] != 'yes') { - if (!isset($this->http_vars['geo_width'])) { - $this->http_vars['geo_width'] = 0; - } - } - - require_once(dirname(dirname(dirname(__FILE__))).'/client_interface/csv/search_results_csv.php'); - - $geocode_results = null; - $ignore_me = null; - $meeting_objects = array(); - $formats_ar = array (); - $result2 = DisplaySearchResultsCSV($this->http_vars, $ignore_me, $geocode_results, $meeting_objects); - - if (is_array($meeting_objects) && count($meeting_objects) && is_array($formats_ar)) { - foreach ($meeting_objects as $one_meeting) { - $formats = $one_meeting->GetMeetingDataValue('formats'); - - foreach ($formats as $format) { - if ($format && ($format instanceof c_comdef_format)) { - $format_shared_id = $format->GetSharedID(); - $formats_ar[$format_shared_id] = $format; - } - } - } - } - - if (isset($this->http_vars['data_field_key']) && $this->http_vars['data_field_key']) { - // At this point, we have everything in a CSV. We separate out just the field we want. - $temp_keyed_array = array(); - $result = explode("\n", $result); - $keys = array_shift($result); - $keys = explode("\",\"", trim($keys, '"')); - $the_keys = explode(',', $this->http_vars['data_field_key']); - - $result = array(); - foreach ($result2 as $row) { - if ($row) { - $index = 0; - $row = explode('","', trim($row, '",')); - $row_columns = array(); - foreach ($row as $column) { - if (!$column) { - $column = ' '; - } - if (in_array($keys[$index++], $the_keys)) { - array_push($row_columns, $column); - } - } - $result[$row[0]] = '"'.implode('","', $row_columns).'"'; - } - } - - $the_keys = array_intersect($keys, $the_keys); - $result2 = '"'.implode('","', $the_keys)."\"\n".implode("\n", $result); - } - - - $result = "\ngetMainURL()."client_interface/xsd/GetSearchResults.php\">"; - $result .= $this->TranslateCSVToXML($result2); - if ((isset($http_vars['get_used_formats']) || isset($http_vars['get_formats_only'])) && $formats_ar && is_array($formats_ar) && count($formats_ar)) { - if (isset($http_vars['get_formats_only'])) { - $result = "\ngetMainURL()."client_interface/xsd/GetFormats.php\">"; - } else { - $result .= ""; - } - $result3 = GetFormats($server, $langs, null, $formats_ar); - $result .= TranslateToXML($result3); - - $result .= ""; - } - - $result .= isset($http_vars['get_formats_only']) ? "" : ""; - - return $result; - } - - /********************************************************************************************************//** - \brief This fulfills a user request to return format information. - - \returns XML, containing the answer. - ************************************************************************************************************/ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function process_format_info() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $ret = ''; - - if ($this->basic_user_validation()) { - $format_ids = array(); - - // See if we are receiving a request for just specific formats, or if we are being asked for all of them. - if (isset($this->http_vars['format_id']) && intval(trim($this->http_vars['format_id']))) { - $format_ids[] = intval(trim($this->http_vars['format_id'])); - } elseif (isset($this->http_vars['format_id']) && is_array($this->http_vars['format_id']) && count($this->http_vars['format_id'])) { - foreach ($this->http_vars['format_id'] as $format) { - $format_ids[] = intval(trim($format)); - } - } else { - $format_ids = null; - } - - $lang = $this->server->GetLocalLang(); - if (isset($this->http_vars['lang']) && trim($this->http_vars['lang'])) { - $lang = strtolower(trim($this->http_vars['lang'])); - } - - $returned_formats = array(); // We will be returning our formats in this. - $format_objects = $this->server->GetFormatsObj()->GetFormatsByLanguage($lang); // Get all the formats (not just the ones used, but ALL of them). - - // Filter for requested formats in the requested language. - foreach ($format_objects as $format) { - if (!$format_ids || in_array(intval($format->GetSharedID()), $format_ids)) { - $returned_formats[] = $format; - } - } - - // At this point, we have a complete array of just the format[s] that will be returned. Time to make some XML... - $index = 0; - - // We will find out which formats actually appear, somewhere in the DB, and indicate that when we give the info. - $used_formats = $this->server->GetUsedFormatsArray(); - $used_ids = array(); - - foreach ($used_formats as $format) { - $used_ids[] = intval($format->GetSharedID()); - } - - foreach ($returned_formats as $format) { - $ret .= ''; - $id = intval($format->GetSharedID()); - $ret.= ''.c_comdef_htmlspecialchars($format->GetKey()).''; - $ret.= ''.c_comdef_htmlspecialchars($format->GetLocalName()).''; - $ret.= ''.c_comdef_htmlspecialchars($format->GetLocalDescription()).''; - $ret.= ''.c_comdef_htmlspecialchars($lang).''; - $ret.= ''.$id.''; - $world_id = trim($format->GetWorldID()); - if (isset($world_id) && $world_id) { - $ret.= ''.c_comdef_htmlspecialchars($world_id).''; - } - - // If this is used somewehere, we indicate it here. - if (in_array($id, $used_ids)) { - $ret.= '1'; - } - - $ret .= ''; - } - $ret = "\ngetMainURL()."client_interface/xsd/GetFormats.php\">$ret"; - } else { - $ret = '

NOT AUTHORIZED

'; - } - - return $ret; - } - - /********************************************************************************************************//** - \brief This fulfills a user request to return Service Body information for multiple Service bodies. - - \returns XML, containing the answer. - ************************************************************************************************************/ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function process_service_bodies_info_request() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $ret = ''; - - if ($this->basic_user_validation()) { - $service_body_ids = array(); - - // Look to see if the caller is asking for particular Service bodies. - if (isset($this->http_vars['sb_id']) && $this->http_vars['sb_id']) { - if (!is_array($this->http_vars['sb_id'])) { - $service_body_ids[] = intval(trim($this->http_vars['sb_id'])); - } else { - foreach ($this->http_vars['sb_id'] as $id) { - if (intval(trim($id))) { - $service_body_ids[] = intval(trim($id)); - } - } - } - } - - // If we have a request for individual Service bodies, then we just return those ones. - if (isset($service_body_ids) && is_array($service_body_ids) && count($service_body_ids)) { - foreach ($service_body_ids as $id) { - $ret .= $this->process_service_body_info_request($id); - } - } else // If they are not looking for particular bodies, then we return the whole kit & kaboodle. - { - $service_bodies = $this->server->GetServiceBodyArray(); - - foreach ($service_bodies as $service_body) { - if (isset($this->http_vars['flat']) || !$service_body->GetOwnerIDObject()) { // We automatically include top-level Service bodies here, and let ones with parents sort themselves out. - $ret .= $this->process_service_body_info_request($service_body->GetID()); - } - } - } - - $ret = "\ngetMainURL()."client_interface/xsd/HierServiceBodies.php\">$ret"; - } else { - $ret = '

NOT AUTHORIZED

'; - } - - return $ret; - } - - /********************************************************************************************************//** - \brief This fulfills a user request to return Service Body information. - - \returns XML, containing the answer. - ************************************************************************************************************/ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function process_service_body_info_request( - $in_service_body_id ///< The ID of the Service body being requested. - ) { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $ret = ''; - // Belt and suspenders. We need to make sure the user is authorized. - if ($this->basic_user_validation()) { - if (!in_array($in_service_body_id, $this->handled_service_body_ids)) { - $this->handled_service_body_ids[] = $in_service_body_id; - $service_body = $this->server->GetServiceBodyByIDObj($in_service_body_id); - - if (isset($service_body) && ($service_body instanceof c_comdef_service_body)) { - // Everyone gets the type, URI, name, description and parent Service body. - $name = $service_body->GetLocalName(); - $description = $service_body->GetLocalDescription(); - $uri = $service_body->GetURI(); - $helpline = $service_body->GetHelpline(); - $type = $service_body->GetSBType(); - - $parent_service_body_id = 0; - $parent_service_body_name = ""; - $parent_service_body_type = ""; - - $parent_service_body = $service_body->GetOwnerIDObject(); - - if (isset($parent_service_body) && $parent_service_body) { - $parent_service_body_id = intval($parent_service_body->GetID()); - $parent_service_body_name = $parent_service_body->GetLocalName(); - $parent_service_body_type = $parent_service_body->GetSBType(); - } - - $principal_user = $service_body->GetPrincipalUserObj(); - $principal_user_id = intval($principal_user->GetID()); - - // Scan for our various editors. - $guest_editors = $this->server->GetUsersByLevelObj(_USER_LEVEL_OBSERVER, true); // Observer or greater. - $service_body_editors = array(); - $meeting_list_editors = array(); - $observers = array(); - - foreach ($guest_editors as $editor) { - if ($service_body->UserCanEdit($editor)) { // We will have at least one of these, as the principal user needs to be listed. - array_push($service_body_editors, $editor); - } elseif ($service_body->UserCanEditMeetings($editor)) { - array_push($meeting_list_editors, $editor); - } elseif ($service_body->UserCanObserve($editor)) { - array_push($observers, $editor); - } - } - - // Scan for direct descendant child Service bodies. - $children = array(); - $service_bodies = $this->server->GetServiceBodyArray(); - - foreach ($service_bodies as $child) { - if ($child->IsOwnedBy($in_service_body_id, true)) { - $children[] = $child; - } - } - - // We check to see which editors are mentioned in this Service body. - $guest_editors = $service_body->GetEditors(); - - // See if we have rights to edit this Service body. Just for the heck of it, we check the user level (not really necessary, but belt and suspenders). - $this_user_can_edit_the_body = ($this->server->GetCurrentUserObj()->GetUserLevel() == _USER_LEVEL_SERVICE_BODY_ADMIN) && $service_body->UserCanEdit(); - - $contact_email = null; - - // Service Body Admins (with permission for the body) get more info. - if ($this_user_can_edit_the_body) { - $contact_email = $service_body->GetContactEmail(); - } - - // At this point, we have all the information we need to build the response XML. - $ret = ''; - $ret .= ''.c_comdef_htmlspecialchars($this->my_localized_strings['service_body_types'][$type]).''; - if (isset($description) && $description) { - $ret .= ''.c_comdef_htmlspecialchars($description).''; - } - if (isset($uri) && $uri) { - $ret .= ''.c_comdef_htmlspecialchars($uri).''; - } - if (isset($helpline) && $helpline) { - $ret .= ''.c_comdef_htmlspecialchars($helpline).''; - } - if (isset($parent_service_body) && $parent_service_body) { - $ret .= ''.c_comdef_htmlspecialchars($parent_service_body_name).''; - } - if ($this_user_can_edit_the_body && isset($contact_email) && $contact_email) { - $ret .= ''.c_comdef_htmlspecialchars($contact_email).''; - } - - $ret .= ''; - if (isset($service_body_editors) && is_array($service_body_editors) && count($service_body_editors)) { - // We will have at least one of these (the principal user). - // These are the users that can directly manipulate the Service body. - $ret .= ''; - foreach ($service_body_editors as $editor) { - $editor_id = intval($editor->GetID()); - $ret .= ''; - } - $ret .= ''; - } - - // These are users that can't manipulate the Service body, but can edit meetings. - if (isset($meeting_list_editors) && is_array($meeting_list_editors) && count($meeting_list_editors)) { - $ret .= ''; - foreach ($meeting_list_editors as $editor) { - $editor_id = intval($editor->GetID()); - $ret .= ''; - } - $ret .= ''; - } - - // These are users that can only see hidden fields in meetings. - if (isset($observers) && is_array($observers) && count($observers)) { - $ret .= ''; - foreach ($observers as $editor) { - $editor_id = intval($editor->GetID()); - $ret .= ''; - } - $ret .= ''; - } - $ret .= ''; - - // If this is a hierarchical response, we embed the children as XML service_body elements. Otherwise, we list them as simple catalog elements. - if (!isset($this->http_vars['flat']) && isset($children) && is_array($children) && count($children)) { - $ret .= ""; - foreach ($children as $child) { - $ret .= $this->process_service_body_info_request($child->GetID()); - } - $ret .= ""; - } elseif (isset($children) && is_array($children) && count($children)) { - $ret .= ''; - foreach ($children as $child) { - $ret .= ''.c_comdef_htmlspecialchars($child->GetLocalName()).''; - } - $ret .= ''; - } - - $ret .= ''; - } - } - } else { - $ret = '

NOT AUTHORIZED

'; - } - - return $ret; - } - - /********************************************************************************************************//** - \brief This fulfills a user request to report the rights for the logged-in user. - - \returns XML, containing the answer. - ************************************************************************************************************/ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function process_capabilities_request() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $ret = ''; - $service_bodies = $this->server->GetServiceBodyArray(); - - // We will fill these three arrays, depending on the users' rights for a given Service body. - $my_meeting_observer_service_bodies = array(); - $my_meeting_editor_service_bodies = array(); - $my_editable_service_bodies = array(); - - $user_obj = $this->server->GetCurrentUserObj(); - if ($this->basic_user_validation()) { - // We cycle through all the Service bodies, and look for ones in which we have permissions. - // We use the Service body IDs to key them in associative arrays. - foreach ($service_bodies as $service_body) { - if (($user_obj->GetUserLevel() == _USER_LEVEL_SERVICE_BODY_ADMIN) && $service_body->UserCanEdit()) { // We are a full Service body editor, with rights to edit the Service body itself (as well as all its meetings). - $my_editable_service_bodies['sb_'.$service_body->GetID()] = $service_body; - } elseif ((($user_obj->GetUserLevel() == _USER_LEVEL_SERVICE_BODY_ADMIN) || ($user_obj->GetUserLevel() == _USER_LEVEL_OBSERVER)) && $service_body->UserCanObserve()) { // We are a "guest" editor, or an observer (depends on our user level). - // Again, we keep checking credentials, over and over again. - if ($user_obj->GetUserLevel() == _USER_LEVEL_OBSERVER) { - $my_meeting_observer_service_bodies['sb_'.$service_body->GetID()] = $service_body; - } elseif ($service_body->UserCanEditMeetings()) { - $my_meeting_editor_service_bodies['sb_'.$service_body->GetID()] = $service_body; - } - } - } - // Now, we grant rights to Service bodies that are implicit from other rights (for example, a Service Body Admin can also observe and edit meetings). - - // A full Service Body Admin can edit meetings in that Service body. - foreach ($my_editable_service_bodies as $service_body) { - $my_meeting_editor_service_bodies['sb_'.$service_body->GetID()] = $service_body; - } - - // An editor (whether an admin or a "guest") also has observe rights. - foreach ($my_meeting_editor_service_bodies as $service_body) { - $my_meeting_observer_service_bodies['sb_'.$service_body->GetID()] = $service_body; - } - - // At this point, we have 3 arrays (or fewer), filled with Service bodies that we have rights on. It is entirely possible that only one of them could be filled, and it may only have one member. - - // We start to construct the XML filler. - foreach ($service_bodies as $service_body) { - // If we can observe, then we have at least one permission for this Service body. - if (isset($my_meeting_observer_service_bodies['sb_'.$service_body->GetID()]) && $my_meeting_observer_service_bodies['sb_'.$service_body->GetID()]) { - $ret .= ''; - } - } - // Create a proper XML wrapper for the response data. - $ret = "\ngetMainURL()."client_interface/xsd/AdminPermissions.php\">$ret"; - // We now have XML that states the current user's permission levels in all Service bodies. - } else { - $ret = '

NOT AUTHORIZED

'; - } - - return $ret; - } - - /********************************************************************************************************//** - \brief This fulfills a user request to return the current users info. - - \returns XML, containing the answer. - ************************************************************************************************************/ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function process_user_info() - { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - $ret = ''; - $user_obj = $this->server->GetCurrentUserObj(); - - if ($this->basic_user_validation()) { - $ret = ''; - // Create a proper XML wrapper for the response data. - $ret = "\ngetMainURL()."client_interface/xsd/UserInfo.php\">$ret"; - // We now have XML that states the current user's permission levels in all Service bodies. - } else { - $ret = '

NOT AUTHORIZED

'; - } - - return $ret; - } - - /*******************************************************************/ - /** - \brief Translates CSV to XML. - - \returns an XML string, with all the data in the CSV. - */ - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - public function TranslateCSVToXML( - $in_csv_data ///< An array of CSV data, with the first element being the field names. - ) { - // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps - require_once(dirname(dirname(dirname(__FILE__))).'/server/shared/Array2XML.php'); - $temp_keyed_array = array(); - $in_csv_data = explode("\n", $in_csv_data); - $keys = array_shift($in_csv_data); - $keys = rtrim(ltrim($keys, '"'), '",'); - $keys = preg_split('/","/', $keys); - - foreach ($in_csv_data as $row) { - if ($row) { - $line = null; - $index = 0; - $row_t = rtrim(ltrim($row, '"'), '",'); - $row_t = preg_split('/","/', $row_t); - foreach ($row_t as $column) { - if (isset($column)) { - $line[$keys[$index++]] = trim($column); - } - } - array_push($temp_keyed_array, $line); - } - } - - $out_xml_data = array2xml($temp_keyed_array, 'not_used', false); - - return $out_xml_data; - } -} diff --git a/src/legacy/local_server/server_admin/c_comdef_login.php b/src/legacy/local_server/server_admin/c_comdef_login.php deleted file mode 100755 index aa0a459ce..000000000 --- a/src/legacy/local_server/server_admin/c_comdef_login.php +++ /dev/null @@ -1,270 +0,0 @@ -. -*/ -defined('BMLT_EXEC') or die('Cannot Execute Directly'); // Makes sure that this file is in the correct context. - -require_once(dirname(dirname(dirname(__FILE__)))."/server/c_comdef_server.class.php"); -require_once(dirname(dirname(dirname(__FILE__)))."/server/shared/classes/comdef_utilityclasses.inc.php"); - -include(dirname(dirname(dirname(__FILE__))).'/server/config/get-config.php'); - -$t_server = c_comdef_server::MakeServer(); // We initialize the server. - -$lang_enum = $t_server->GetServer()->GetLocalLang(); - -// We use a cookie to store the language pref. -$lang_enum = request()->cookie('bmlt_admin_lang_pref', $lang_enum); - -if (isset($http_vars['lang_enum']) && $http_vars['lang_enum']) { - $lang_enum = $http_vars['lang_enum']; -} - -if (isset($g_enable_language_selector) && $g_enable_language_selector) { - cookie()->queue('bmlt_admin_lang_pref', $lang_enum, 60 * 24 * 365); -} - -if (isset($_GET['bad_login_form'])) { - $localized_strings = c_comdef_server::GetLocalStrings(); - die('

'.c_comdef_htmlspecialchars($localized_strings['comdef_server_admin_strings']['not_auth_3']).'

'.c_comdef_LoginForm($server).''); -} - -$user_obj = $t_server->GetCurrentUserObj(); -if (is_null($user_obj)) { - echo c_comdef_LoginForm($t_server); -} elseif (!($user_obj instanceof c_comdef_user) || ($user_obj->GetUserLevel() == _USER_LEVEL_DEACTIVATED)) { - // If the login is invalid, we terminate the whole kit and kaboodle, and inform the user they are persona non grata. - $localized_strings = c_comdef_server::GetLocalStrings(); - die('

'.c_comdef_htmlspecialchars($localized_strings['comdef_server_admin_strings']['not_auth_1']).'

'.c_comdef_htmlspecialchars($localized_strings['comdef_server_admin_strings']['not_auth_2']).'

'); -} else { - // Get the display strings. - $localized_strings = c_comdef_server::GetLocalStrings(); - - if (!isset($supress_header) || !$supress_header) { - echo ''; - echo '

'; - } -} - - -$t_server = null; - -/***********************************************************************/ -/** \brief Copied verbatim from here: http://stackoverflow.com/questions/6768793/get-the-full-url-in-php -\returns a string, with the full URI. -*/ -function url_origin($s, $use_forwarded_host = false) -{ - $ssl = ( !empty($s['HTTPS']) && $s['HTTPS'] == 'on' ) ? true:false; - $sp = strtolower($s['SERVER_PROTOCOL']); - $protocol = substr($sp, 0, strpos($sp, '/')) . ( ( $ssl ) ? 's' : '' ); - $port = $s['SERVER_PORT']; - $port = ( (!$ssl && $port=='80') || ($ssl && $port=='443') ) ? '' : ':'.$port; - $host = ( $use_forwarded_host && isset($s['HTTP_X_FORWARDED_HOST']) ) ? $s['HTTP_X_FORWARDED_HOST'] : (isset($s['HTTP_HOST']) ? $s['HTTP_HOST'] : null); - $host = isset($host) ? $host : $s['SERVER_NAME'] . $port; - return $protocol . '://' . $host; -} - -/***********************************************************************/ -/** \brief Copied verbatim from here: http://stackoverflow.com/questions/6768793/get-the-full-url-in-php -\returns a string, with the full URI. -*/ -function full_url($s, $use_forwarded_host = false) -{ - return url_origin($s, $use_forwarded_host) . $s['REQUEST_URI']; -} - -/********************************************************************************************************//** -\brief This function parses the main server version from the XML file. -\returns a string, containing the version info and banner. -************************************************************************************************************/ -function GetServerInfo() -{ - $ret = null; - - $ret['version'] = config()->get('app.version'); - - $config_file_path = dirname(dirname(dirname(__FILE__))).'/server/config/get-config.php'; - - if (file_exists($config_file_path)) { - include($config_file_path); - $localized_strings = c_comdef_server::GetLocalStrings(); - if (isset($bmlt_title) && trim($bmlt_title)) { - $ret['title'] = trim($bmlt_title); - } else { - $ret['title'] = $localized_strings['comdef_server_admin_strings']['login_banner']; - } - if (isset($banner_text) && trim($banner_text)) { - $ret['banner_text'] = trim($banner_text); - } else { - $ret['banner_text'] = $localized_strings['comdef_server_admin_strings']['login_underbanner']; - } - } - - return $ret; -} - -/*******************************************************************/ -/** \brief Returns HTML for the login form. If the user is not logged - in, then they get the form. Otherwise, the login is processed, or - the user is vetted. - - \returns a string, containing the form HTML. -*/ -function c_comdef_LoginForm( - &$in_server ///< A reference to an instance of c_comdef_server -) { - include(dirname(dirname(dirname(__FILE__))).'/server/config/get-config.php'); - - $http_vars = array_merge($_GET, $_POST); - - $localized_strings = c_comdef_server::GetLocalStrings(); - $server_info = GetServerInfo(); - - global $comdef_global_language; - - if (isset($http_vars) && is_array($http_vars) && count($http_vars) && isset($http_vars['lang_enum'])) { - $lang_name = $http_vars['lang_enum']; - - if (file_exists(dirname(__FILE__)."/lang/".$lang_name."/name.txt")) { - $comdef_global_language = $lang_name; - } - } elseif (session('lang_enum')) { - $lang_name = session('lang_enum'); - - if (file_exists(dirname(__FILE__)."/lang/".$lang_name."/name.txt")) { - $comdef_global_language = $lang_name; - } - } - - session()->put('lang_enum', $comdef_global_language); - - $ret = ''; - - return $ret; -} diff --git a/src/legacy/local_server/server_admin/index.htm b/src/legacy/local_server/server_admin/index.htm deleted file mode 100755 index e69de29bb..000000000 diff --git a/src/legacy/local_server/server_admin/jquery.slim.min.js b/src/legacy/local_server/server_admin/jquery.slim.min.js deleted file mode 100644 index 36b4e1a13..000000000 --- a/src/legacy/local_server/server_admin/jquery.slim.min.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! jQuery v3.5.1 -ajax,-ajax/jsonp,-ajax/load,-ajax/script,-ajax/var/location,-ajax/var/nonce,-ajax/var/rquery,-ajax/xhr,-manipulation/_evalUrl,-deprecated/ajax-event-alias,-effects,-effects/Tween,-effects/animatedSelector | (c) JS Foundation and other contributors | jquery.org/license */ -!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(g,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,v=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,y=n.hasOwnProperty,a=y.toString,l=a.call(Object),m={},b=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},x=function(e){return null!=e&&e===e.window},w=g.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function C(e,t,n){var r,i,o=(n=n||w).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function T(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.5.1 -ajax,-ajax/jsonp,-ajax/load,-ajax/script,-ajax/var/location,-ajax/var/nonce,-ajax/var/rquery,-ajax/xhr,-manipulation/_evalUrl,-deprecated/ajax-event-alias,-effects,-effects/Tween,-effects/animatedSelector",E=function(e,t){return new E.fn.init(e,t)};function d(e){var t=!!e&&"length"in e&&e.length,n=T(e);return!b(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+R+")"+R+"*"),U=new RegExp(R+"|>"),V=new RegExp(W),X=new RegExp("^"+B+"$"),Q={ID:new RegExp("^#("+B+")"),CLASS:new RegExp("^\\.("+B+")"),TAG:new RegExp("^("+B+"|[*])"),ATTR:new RegExp("^"+M),PSEUDO:new RegExp("^"+W),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+R+"*(even|odd|(([+-]|)(\\d*)n|)"+R+"*(?:([+-]|)"+R+"*(\\d+)|))"+R+"*\\)|)","i"),bool:new RegExp("^(?:"+I+")$","i"),needsContext:new RegExp("^"+R+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+R+"*((?:-\\d)?\\d*)"+R+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,G=/^(?:input|select|textarea|button)$/i,K=/^h\d$/i,J=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+R+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){C()},ae=xe(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{O.apply(t=P.call(d.childNodes),d.childNodes),t[d.childNodes.length].nodeType}catch(e){O={apply:t.length?function(e,t){q.apply(e,P.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,d=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==d&&9!==d&&11!==d)return n;if(!r&&(C(e),e=e||T,E)){if(11!==d&&(u=Z.exec(t)))if(i=u[1]){if(9===d){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return O.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&p.getElementsByClassName&&e.getElementsByClassName)return O.apply(n,e.getElementsByClassName(i)),n}if(p.qsa&&!k[t+" "]&&(!v||!v.test(t))&&(1!==d||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===d&&(U.test(t)||_.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&p.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=A)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+be(l[o]);c=l.join(",")}try{return O.apply(n,f.querySelectorAll(c)),n}catch(e){k(t,!0)}finally{s===A&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>x.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[A]=!0,e}function ce(e){var t=T.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)x.attrHandle[n[r]]=t}function de(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function pe(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in p=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},C=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:d;return r!=T&&9===r.nodeType&&r.documentElement&&(a=(T=r).documentElement,E=!i(T),d!=T&&(n=T.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),p.scope=ce(function(e){return a.appendChild(e).appendChild(T.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),p.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),p.getElementsByTagName=ce(function(e){return e.appendChild(T.createComment("")),!e.getElementsByTagName("*").length}),p.getElementsByClassName=J.test(T.getElementsByClassName),p.getById=ce(function(e){return a.appendChild(e).id=A,!T.getElementsByName||!T.getElementsByName(A).length}),p.getById?(x.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},x.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(x.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},x.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),x.find.TAG=p.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):p.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},x.find.CLASS=p.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(p.qsa=J.test(T.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+R+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+R+"*(?:value|"+I+")"),e.querySelectorAll("[id~="+A+"-]").length||v.push("~="),(t=T.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+R+"*name"+R+"*="+R+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+A+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=T.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+R+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(p.matchesSelector=J.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){p.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",W)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=J.test(a.compareDocumentPosition),y=t||J.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!p.sortDetached&&t.compareDocumentPosition(e)===n?e==T||e.ownerDocument==d&&y(d,e)?-1:t==T||t.ownerDocument==d&&y(d,t)?1:u?H(u,e)-H(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==T?-1:t==T?1:i?-1:o?1:u?H(u,e)-H(u,t):0;if(i===o)return de(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?de(a[r],s[r]):a[r]==d?-1:s[r]==d?1:0}),T},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(C(e),p.matchesSelector&&E&&!k[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||p.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){k(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return Q.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&V.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+R+")"+e+"("+R+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function D(e,n,r){return b(n)?E.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?E.grep(e,function(e){return e===n!==r}):"string"!=typeof n?E.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(E.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||L,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:j.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof E?t[0]:t,E.merge(this,E.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:w,!0)),k.test(r[1])&&E.isPlainObject(t))for(r in t)b(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=w.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):b(e)?void 0!==n.ready?n.ready(e):e(E):E.makeArray(e,this)}).prototype=E.fn,L=E(w);var q=/^(?:parents|prev(?:Until|All))/,O={children:!0,contents:!0,next:!0,prev:!0};function P(e,t){while((e=e[t])&&1!==e.nodeType);return e}E.fn.extend({has:function(e){var t=E(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,pe=/^$|^module$|\/(?:java|ecma)script/i;le=w.createDocumentFragment().appendChild(w.createElement("div")),(ce=w.createElement("input")).setAttribute("type","radio"),ce.setAttribute("checked","checked"),ce.setAttribute("name","t"),le.appendChild(ce),m.checkClone=le.cloneNode(!0).cloneNode(!0).lastChild.checked,le.innerHTML="",m.noCloneChecked=!!le.cloneNode(!0).lastChild.defaultValue,le.innerHTML="",m.option=!!le.lastChild;var he={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ge(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&S(e,t)?E.merge([e],n):n}function ve(e,t){for(var n=0,r=e.length;n",""]);var ye=/<|&#?\w+;/;function me(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),d=[],p=0,h=e.length;p\s*$/g;function Le(e,t){return S(e,"table")&&S(11!==t.nodeType?t:t.firstChild,"tr")&&E(e).children("tbody")[0]||e}function je(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Oe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n
",2===ft.childNodes.length),E.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(m.createHTMLDocument?((r=(t=w.implementation.createHTMLDocument("")).createElement("base")).href=w.location.href,t.head.appendChild(r)):t=w),o=!n&&[],(i=k.exec(e))?[t.createElement(i[1])]:(i=me([e],t,o),o&&o.length&&E(o).remove(),E.merge([],i.childNodes)));var r,i,o},E.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=E.css(e,"position"),c=E(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=E.css(e,"top"),u=E.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),b(t)&&(t=t.call(e,n,E.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):("number"==typeof f.top&&(f.top+="px"),"number"==typeof f.left&&(f.left+="px"),c.css(f))}},E.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){E.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===E.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===E.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=E(e).offset()).top+=E.css(e,"borderTopWidth",!0),i.left+=E.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-E.css(r,"marginTop",!0),left:t.left-i.left-E.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===E.css(e,"position"))e=e.offsetParent;return e||re})}}),E.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;E.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),E.each(["top","left"],function(e,n){E.cssHooks[n]=Fe(m.pixelPosition,function(e,t){if(t)return t=We(e,n),Ie.test(t)?E(e).position()[n]+"px":t})}),E.each({Height:"height",Width:"width"},function(a,s){E.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){E.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?E.css(e,t,i):E.style(e,t,n,i)},s,n?e:void 0,n)}})}),E.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),E.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){E.fn[n]=function(e,t){return 0 element (don't - specify a "type" attribute), and give it a GET parameter of filename, - which will equal the file path to the JavaScript file. - - For security purposes, the file must always be a ".js" file, and you can't - go out of the directory in which this file is located. - - This file is part of the Basic Meeting List Toolbox (BMLT). - - Find out more at: https://bmlt.app - - BMLT is free software: you can redistribute it and/or modify - it under the terms of the MIT License. - - BMLT is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - MIT License for more details. - - You should have received a copy of the MIT License along with this code. - If not, see . -*/ -//define ( '__DEBUG_MODE__', 1 ); // Uncomment to make the CSS and JavaScript easier to trace (and less efficient). - $pathname = $_GET['filename']; -if (!preg_match("|/|", $pathname)) { - if (preg_match("|.*?\.js$|", $pathname)) { - $pathname = dirname(__FILE__)."/$pathname"; - $opt = file_get_contents($pathname); - if (!defined('__DEBUG_MODE__')) { - $opt = preg_replace("|\/\*.*?\*\/|s", "", $opt); - $opt = preg_replace('#(?. -*/ -defined('BMLT_EXEC') or define('BMLT_EXEC', 1); -require_once(dirname(dirname(dirname(__FILE__))).'/server/config/get-config.php'); - -// We only do this if the capability has been enabled in the auto-config file. -if (isset($g_enable_semantic_admin) && ($g_enable_semantic_admin == true)) { - require_once(dirname(dirname(dirname(__FILE__))).'/server/c_comdef_server.class.php'); - - /*************************************************************************************************************** - ************************************************* MAIN CONTEXT ************************************************* - ***************************************************************************************************************/ - - $http_vars = array_merge($_GET, $_POST); - - // Create an HTTP path to our XML file. We build it manually, in case this file is being used elsewhere, or we have a redirect in the domain. - // We allow it to be used as HTTPS. - $url_path = GetURLToMainServerDirectory().'local_server/server_admin/json.php'; - $lang_enum = ''; - $login_call = false; // We only allow login with the login call. That's to prevent users constantly sending cleartext login info. - - // We use a cookie to store the language pref. - $lang_enum = request()->cookie('bmlt_admin_lang_pref', $lang_enum); - - if (isset($http_vars['lang_enum']) && $http_vars['lang_enum']) { - $lang_enum = $http_vars['lang_enum']; - } - - $http_vars['lang_enum'] = $lang_enum; // Quick and dirty way to ensure that this gets properly propagated. - - if ($lang_enum) { - cookie()->queue('bmlt_admin_lang_pref', $lang_enum, 60 * 24 * 365); - } - - require_once(dirname(dirname(dirname(__FILE__))).'/server/shared/classes/comdef_utilityclasses.inc.php'); - require_once(dirname(dirname(dirname(__FILE__))).'/server/shared/Array2Json.php'); - require_once(dirname(dirname(__FILE__)).'/db_connect.php'); - - DB_Connect_and_Upgrade(); - - $server = c_comdef_server::MakeServer(); - - if ($server instanceof c_comdef_server) { - $user_obj = $server->GetCurrentUserObj(); - if (!($user_obj instanceof c_comdef_user) || ($user_obj->GetUserLevel() == _USER_LEVEL_DEACTIVATED) || ($user_obj->GetUserLevel() == _USER_LEVEL_SERVER_ADMIN) || ($user_obj->GetID() == 1)) { - c_comdef_LogoutUser(); - die('NOT AUTHORIZED'); - } - - if (isset($http_vars['admin_action']) && $http_vars['admin_action']) { // Must have an admin_action. - require_once(dirname(__FILE__).'/c_comdef_admin_xml_handler.class.php'); - - $handler = new c_comdef_admin_xml_handler($http_vars, $server); - - if ($handler instanceof c_comdef_admin_xml_handler) { - $ret = $handler->process_commands(); - $ret = simplexml_load_string($ret); - $json = json_encode((Array)$ret, JSON_NUMERIC_CHECK); - - $pattern = '/\{\"\@attributes\"\:\{(.*?)\}\}/'; // Replace attribute objects with direct objects, to remove the extra layer. - $replacement = '{\1}'; - do { - $old_json = $json; - $json = preg_replace($pattern, $replacement, $json); - } while ($json && ($old_json != $json)); - - $pattern = '/\"\@attributes\"\:\{(\"sequence_index\"\:(\d+?))\}\,/'; - $replacement = ''; - do { - $old_json = $json; - $json = preg_replace($pattern, $replacement, $json); - } while ($json && ($old_json != $json)); - - $pattern = '/\"row\"\:\{\"sequence_index\"\:(\d*?)\}\,/'; // Replace sequence index object, to remove the extra layer. - do { - $old_json = $json; - $json = preg_replace($pattern, "", $json); - } while ($json && ($old_json != $json)); - - if (isset($json) && $json) { - header('Content-Type:application/json; charset=UTF-8'); - if (zlib_get_coding_type() === false) { - ob_start("ob_gzhandler"); - } else { - ob_start(); - } - echo ( $json ); - ob_end_flush(); - } else { - $ret = 'ERROR'; - } - - // Just making sure... - unset($handler); - unset($server); - unset($http_vars); - } else { - $ret = 'ERROR'; - } - } else { - die('BAD ADMIN ACTION'); - } - } else { - die('NO SERVER!'); - } -} diff --git a/src/legacy/local_server/server_admin/json2.js b/src/legacy/local_server/server_admin/json2.js deleted file mode 100755 index 7479fbea3..000000000 --- a/src/legacy/local_server/server_admin/json2.js +++ /dev/null @@ -1,485 +0,0 @@ -/* - json2.js - 2012-10-08 - - Public Domain. - - NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. - - See http://www.JSON.org/js.html - - - This code should be minified before deployment. - See http://javascript.crockford.com/jsmin.html - - USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO - NOT CONTROL. - - - This file creates a global JSON object containing two methods: stringify - and parse. - - JSON.stringify(value, replacer, space) - value any JavaScript value, usually an object or array. - - replacer an optional parameter that determines how object - values are stringified for objects. It can be a - function or an array of strings. - - space an optional parameter that specifies the indentation - of nested structures. If it is omitted, the text will - be packed without extra whitespace. If it is a number, - it will specify the number of spaces to indent at each - level. If it is a string (such as '\t' or ' '), - it contains the characters used to indent at each level. - - This method produces a JSON text from a JavaScript value. - - When an object value is found, if the object contains a toJSON - method, its toJSON method will be called and the result will be - stringified. A toJSON method does not serialize: it returns the - value represented by the name/value pair that should be serialized, - or undefined if nothing should be serialized. The toJSON method - will be passed the key associated with the value, and this will be - bound to the value - - For example, this would serialize Dates as ISO strings. - - Date.prototype.toJSON = function (key) { - function f(n) { - // Format integers to have at least two digits. - return n < 10 ? '0' + n : n; - } - - return this.getUTCFullYear() + '-' + - f(this.getUTCMonth() + 1) + '-' + - f(this.getUTCDate()) + 'T' + - f(this.getUTCHours()) + ':' + - f(this.getUTCMinutes()) + ':' + - f(this.getUTCSeconds()) + 'Z'; - }; - - You can provide an optional replacer method. It will be passed the - key and value of each member, with this bound to the containing - object. The value that is returned from your method will be - serialized. If your method returns undefined, then the member will - be excluded from the serialization. - - If the replacer parameter is an array of strings, then it will be - used to select the members to be serialized. It filters the results - such that only members with keys listed in the replacer array are - stringified. - - Values that do not have JSON representations, such as undefined or - functions, will not be serialized. Such values in objects will be - dropped; in arrays they will be replaced with null. You can use - a replacer function to replace those with JSON values. - JSON.stringify(undefined) returns undefined. - - The optional space parameter produces a stringification of the - value that is filled with line breaks and indentation to make it - easier to read. - - If the space parameter is a non-empty string, then that string will - be used for indentation. If the space parameter is a number, then - the indentation will be that many spaces. - - Example: - - text = JSON.stringify(['e', {pluribus: 'unum'}]); - // text is '["e",{"pluribus":"unum"}]' - - - text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t'); - // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]' - - text = JSON.stringify([new Date()], function (key, value) { - return this[key] instanceof Date ? - 'Date(' + this[key] + ')' : value; - }); - // text is '["Date(---current time---)"]' - - - JSON.parse(text, reviver) - This method parses a JSON text to produce an object or array. - It can throw a SyntaxError exception. - - The optional reviver parameter is a function that can filter and - transform the results. It receives each of the keys and values, - and its return value is used instead of the original value. - If it returns what it received, then the structure is not modified. - If it returns undefined then the member is deleted. - - Example: - - // Parse the text. Values that look like ISO date strings will - // be converted to Date objects. - - myData = JSON.parse(text, function (key, value) { - var a; - if (typeof value === 'string') { - a = -/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value); - if (a) { - return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], - +a[5], +a[6])); - } - } - return value; - }); - - myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) { - var d; - if (typeof value === 'string' && - value.slice(0, 5) === 'Date(' && - value.slice(-1) === ')') { - d = new Date(value.slice(5, -1)); - if (d) { - return d; - } - } - return value; - }); - - - This is a reference implementation. You are free to copy, modify, or - redistribute. -*/ - -/*jslint evil: true, regexp: true */ - -/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply, - call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours, - getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join, - lastIndex, length, parse, prototype, push, replace, slice, stringify, - test, toJSON, toString, valueOf -*/ - - -// Create a JSON object only if one does not already exist. We create the -// methods in a closure to avoid creating global variables. - -if (typeof JSON !== 'object') { - JSON = {}; -} - -(function () { - 'use strict'; - - function f(n) - { - // Format integers to have at least two digits. - return n < 10 ? '0' + n : n; - } - - if (typeof Date.prototype.toJSON !== 'function') { - Date.prototype.toJSON = function (key) { - - return isFinite(this.valueOf()) - ? this.getUTCFullYear() + '-' + - f(this.getUTCMonth() + 1) + '-' + - f(this.getUTCDate()) + 'T' + - f(this.getUTCHours()) + ':' + - f(this.getUTCMinutes()) + ':' + - f(this.getUTCSeconds()) + 'Z' - : null; - }; - - String.prototype.toJSON = - Number.prototype.toJSON = - Boolean.prototype.toJSON = function (key) { - return this.valueOf(); - }; - } - - var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, - escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, - gap, - indent, - meta = { // table of character substitutions - '\b': '\\b', - '\t': '\\t', - '\n': '\\n', - '\f': '\\f', - '\r': '\\r', - '"' : '\\"', - '\\': '\\\\' - }, - rep; - - - function quote(string) - { - -// If the string contains no control characters, no quote characters, and no -// backslash characters, then we can safely slap some quotes around it. -// Otherwise we must also replace the offending characters with safe escape -// sequences. - - escapable.lastIndex = 0; - return escapable.test(string) ? '"' + string.replace(escapable, function (a) { - var c = meta[a]; - return typeof c === 'string' - ? c - : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); - }) + '"' : '"' + string + '"'; - } - - - function str(key, holder) - { - -// Produce a string from holder[key]. - - var i, // The loop counter. - k, // The member key. - v, // The member value. - length, - mind = gap, - partial, - value = holder[key]; - -// If the value has a toJSON method, call it to obtain a replacement value. - - if (value && typeof value === 'object' && - typeof value.toJSON === 'function') { - value = value.toJSON(key); - } - -// If we were called with a replacer function, then call the replacer to -// obtain a replacement value. - - if (typeof rep === 'function') { - value = rep.call(holder, key, value); - } - -// What happens next depends on the value's type. - - switch (typeof value) { - case 'string': - return quote(value); - - case 'number': - - // JSON numbers must be finite. Encode non-finite numbers as null. - - return isFinite(value) ? String(value) : 'null'; - - case 'boolean': - case 'null': - - // If the value is a boolean or null, convert it to a string. Note: - // typeof null does not produce 'null'. The case is included here in - // the remote chance that this gets fixed someday. - - return String(value); - -// If the type is 'object', we might be dealing with an object or an array or -// null. - - case 'object': - - // Due to a specification blunder in ECMAScript, typeof null is 'object', - // so watch out for that case. - - if (!value) { - return 'null'; - } - - // Make an array to hold the partial results of stringifying this object value. - - gap += indent; - partial = []; - - // Is the value an array? - - if (Object.prototype.toString.apply(value) === '[object Array]') { - // The value is an array. Stringify every element. Use null as a placeholder - // for non-JSON values. - - length = value.length; - for (i = 0; i < length; i += 1) { - partial[i] = str(i, value) || 'null'; - } - - // Join all of the elements together, separated with commas, and wrap them in - // brackets. - - v = partial.length === 0 - ? '[]' - : gap - ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' - : '[' + partial.join(',') + ']'; - gap = mind; - return v; - } - - // If the replacer is an array, use it to select the members to be stringified. - - if (rep && typeof rep === 'object') { - length = rep.length; - for (i = 0; i < length; i += 1) { - if (typeof rep[i] === 'string') { - k = rep[i]; - v = str(k, value); - if (v) { - partial.push(quote(k) + (gap ? ': ' : ':') + v); - } - } - } - } else { - // Otherwise, iterate through all of the keys in the object. - - for (k in value) { - if (Object.prototype.hasOwnProperty.call(value, k)) { - v = str(k, value); - if (v) { - partial.push(quote(k) + (gap ? ': ' : ':') + v); - } - } - } - } - - // Join all of the member texts together, separated with commas, - // and wrap them in braces. - - v = partial.length === 0 - ? '{}' - : gap - ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' - : '{' + partial.join(',') + '}'; - gap = mind; - return v; - } - } - -// If the JSON object does not yet have a stringify method, give it one. - - if (typeof JSON.stringify !== 'function') { - JSON.stringify = function (value, replacer, space) { - -// The stringify method takes a value and an optional replacer, and an optional -// space parameter, and returns a JSON text. The replacer can be a function -// that can replace values, or an array of strings that will select the keys. -// A default replacer method can be provided. Use of the space parameter can -// produce text that is more easily readable. - - var i; - gap = ''; - indent = ''; - -// If the space parameter is a number, make an indent string containing that -// many spaces. - - if (typeof space === 'number') { - for (i = 0; i < space; i += 1) { - indent += ' '; - } - -// If the space parameter is a string, it will be used as the indent string. - } else if (typeof space === 'string') { - indent = space; - } - -// If there is a replacer, it must be a function or an array. -// Otherwise, throw an error. - - rep = replacer; - if (replacer && typeof replacer !== 'function' && - (typeof replacer !== 'object' || - typeof replacer.length !== 'number')) { - throw new Error('JSON.stringify'); - } - -// Make a fake root object containing our value under the key of ''. -// Return the result of stringifying the value. - - return str('', {'': value}); - }; - } - - -// If the JSON object does not yet have a parse method, give it one. - - if (typeof JSON.parse !== 'function') { - JSON.parse = function (text, reviver) { - -// The parse method takes a text and an optional reviver function, and returns -// a JavaScript value if the text is a valid JSON text. - - var j; - - function walk(holder, key) - { - -// The walk method is used to recursively walk the resulting structure so -// that modifications can be made. - - var k, v, value = holder[key]; - if (value && typeof value === 'object') { - for (k in value) { - if (Object.prototype.hasOwnProperty.call(value, k)) { - v = walk(value, k); - if (v !== undefined) { - value[k] = v; - } else { - delete value[k]; - } - } - } - } - return reviver.call(holder, key, value); - } - - -// Parsing happens in four stages. In the first stage, we replace certain -// Unicode characters with escape sequences. JavaScript handles many characters -// incorrectly, either silently deleting them, or treating them as line endings. - - text = String(text); - cx.lastIndex = 0; - if (cx.test(text)) { - text = text.replace(cx, function (a) { - return '\\u' + - ('0000' + a.charCodeAt(0).toString(16)).slice(-4); - }); - } - -// In the second stage, we run the text against regular expressions that look -// for non-JSON patterns. We are especially concerned with '()' and 'new' -// because they can cause invocation, and '=' because it can cause mutation. -// But just to be safe, we want to reject all unexpected forms. - -// We split the second stage into 4 regexp operations in order to work around -// crippling inefficiencies in IE's and Safari's regexp engines. First we -// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we -// replace all simple value tokens with ']' characters. Third, we delete all -// open brackets that follow a colon or comma or that begin the text. Finally, -// we look to see that the remaining characters are only whitespace or ']' or -// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval. - - if (/^[\],:{}\s]*$/ - .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@') - .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']') - .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { -// In the third stage we use the eval function to compile the text into a -// JavaScript structure. The '{' operator is subject to a syntactic ambiguity -// in JavaScript: it can begin a block or an object literal. We wrap the text -// in parens to eliminate the ambiguity. - - j = eval('(' + text + ')'); - -// In the optional fourth stage, we recursively walk the new structure, passing -// each name/value pair to a reviver function for possible transformation. - - return typeof reviver === 'function' - ? walk({'': j}, '') - : j; - } - -// If the text is not JSON parseable, then a SyntaxError is thrown. - - throw new SyntaxError('JSON.parse'); - }; - } -}()); diff --git a/src/legacy/local_server/server_admin/lang/de/data_transfer_strings.php b/src/legacy/local_server/server_admin/lang/de/data_transfer_strings.php deleted file mode 100755 index 6fa2303ec..000000000 --- a/src/legacy/local_server/server_admin/lang/de/data_transfer_strings.php +++ /dev/null @@ -1,22 +0,0 @@ -.*/ - defined('BMLT_EXEC') or die('Cannot Execute Directly'); // Makes sure that this file is in the correct context. - - $comdef_data_transfer_strings = array (); diff --git a/src/legacy/local_server/server_admin/lang/de/install_wizard_strings.php b/src/legacy/local_server/server_admin/lang/de/install_wizard_strings.php deleted file mode 100644 index 70e33865b..000000000 --- a/src/legacy/local_server/server_admin/lang/de/install_wizard_strings.php +++ /dev/null @@ -1,139 +0,0 @@ -.*/ - defined('BMLT_EXEC') or die('Cannot Execute Directly'); // Makes sure that this file is in the correct context. - - global $comdef_install_wizard_strings; - - $comdef_install_wizard_strings = array ( - 'Database_Version_Error' => 'ERROR: You must have PHP Version 5.6 or greater installed on this server!', - 'Database_PDO_Error' => 'ERROR: You do not have PHP PDO installed!', - 'Database_Type_Error' => 'ERROR: Even though you have PDO, you have no database drivers installed!', - 'Database_TestButton_Text' => 'TEST', - 'Database_TestButton_Success' => 'The database connection was successful.', - 'Database_TestButton_Fail' => 'The database connection failed: ', - 'Database_TestButton_Fail2' => 'The database connection failed because there is already an initialized database.', - 'Database_Whitespace_Note' => 'Warning: %s has whitespace at the beginning or end.', - - 'AJAX_Handler_DB_Connect_Error' => 'The database connection failed! Please make sure that the database exists, IS COMPLETELY EMPTY, the user is created, and that user has full permissions on the empty database.', - 'AJAX_Handler_DB_Established_Error' => 'The database already exists, and has been set up! You cannot use this setup to overwrite an existing database!', - 'AJAX_Handler_DB_Incomplete_Error' => 'There is not enough information to initialize the database!', - - 'NoDatabase_Note_AlreadySet' => 'The database has already been initialized with the provided table prefix. Please choose a new one.', - 'NoDatabase_Note_PasswordIssue' => 'You must choose a username and password for the Server Administrator user.', - 'NoServerAdmin_Note_AlreadySet' => 'There is already an existing database, so you cannot set up a Server Administrator account (One already exists).', - 'NeedLongerPasswordNote' => 'This password is too short. It must be at least %d characters long.', - - 'Prev_Button' => 'PREVIOUS', - 'Next_Button' => 'NEXT', - - 'Page_1_Tab' => 'STEP 1: Database', - 'Page_1_Heading' => 'Database Connection Settings', - 'Page_1_Text' => 'Before you can apply the settings on this page, you must set up a new COMPLETELY EMPTY database, and create a database user that has full user rights on that database.', - - 'Database_Name' => 'Database Name:', - 'Database_Name_Default_Text' => 'Enter A Database Name', - 'Database_Type' => 'Database Type:', - 'Database_Host' => 'Database Host:', - 'Database_Host_Default_Text' => 'Enter A Database Host', - 'Database_Host_Additional_Text' => 'This is usually "localhost."', - 'Table_Prefix' => 'Table Prefix:', - 'Table_Prefix_Default_Text' => 'Enter A Table Prefix', - 'Table_Prefix_Additional_Text' => 'Only for multiple root servers sharing a database.', - 'Database_User' => 'Database User:', - 'Database_User_Default_Text' => 'Enter A Database User Name', - 'Database_PW' => 'Database Password:', - 'Database_PW_Default_Text' => 'Enter A Database Password', - 'Database_PW_Additional_Text' => 'Make this an ugly, difficult password. It has a great deal of power, and you will never need to remember it.', - - 'Maps_API_Key_Warning' => 'There is a problem with the Google Maps API Key.', - - 'Page_2_Tab' => 'STEP 2: Google Maps API', - 'Page_2_Heading' => 'Set The Initial Location For Meetings', - 'Page_2_Text' => 'When saving a meeting, the BMLT Root Server uses the Google Maps API to determine the latitude and longitude for the meeting address. These settings are required to allow the BMLT Root Server to communicate with the Google Maps API.', - - 'Page_3_Tab' => 'STEP 3: Server Settings', - 'Page_3_Heading' => 'Set Various Global Server Settings', - 'Page_3_Text' => 'These are a few settings that affect the administration and general configuration of this server. Most server settings are done in the server itself.', - 'Admin_Login' => 'Server Administrator Login:', - 'Admin_Login_Default_Text' => 'Enter A Server Administrator Login', - 'Admin_Login_Additional_Text' => 'This is the login string for the Server Administrator.', - 'Admin_Password' => 'Server Administrator Password:', - 'Admin_Password_Default_Text' => 'Enter A Server Administrator Password', - 'Admin_Password_Additional_Text' => 'Make sure that this is a non-trivial password! It has a great deal of power! (Also, don\'t forget it).', - 'ServerAdminName' => 'Server Administrator', - 'ServerAdminDesc' => 'Main Server Administrator', - 'ServerLangLabel' => 'Default Server Language:', - 'DistanceUnitsLabel' => 'Distance Units:', - 'DistanceUnitsMiles' => 'Miles', - 'DistanceUnitsKM' => 'Kilometres', - 'SearchDepthLabel' => 'Density of Meetings For Automatic Search:', - 'SearchDepthText' => 'This is an approximation of how many meetings need to be found in the automatic radius selection. More meetings means a bigger radius.', - 'HistoryDepthLabel' => 'How Many Meeting Changes To Save:', - 'HistoryDepthText' => 'The longer the history, the larger the database will become.', - 'TitleTextLabel' => 'The Title Of The Administration Screen:', - 'TitleTextDefaultText' => 'Enter A Short Title For the Editing Login Page', - 'BannerTextLabel' => 'Prompt For Administration Login:', - 'BannerTextDefaultText' => 'Enter A Short Prompt For The Login Page', - 'RegionBiasLabel' => 'Region Bias:', - 'PasswordLengthLabel' => 'Minimum Password Length:', - 'PasswordLengthExtraText' => 'This will also affect the Server Administrator password, above.', - 'DurationLabel' => 'Default Meeting Duration:', - 'DurationHourLabel' => 'Hours', - 'DurationMinutesLabel' => 'Minutes', - 'LanguageSelectorEnableLabel' => 'Display Language Selector On Login:', - 'LanguageSelectorEnableExtraText' => 'If you select this, a popup menu will appear in the login screen, so administrators can select their language.', - 'EmailContactEnableLabel' => 'Allow Email Contacts From Meetings:', - 'EmailContactEnableExtraText' => 'If you select this, site visitors will be able to send emails from meeting records.', - - 'Page_4_Tab' => 'STEP 4: Save The Settings', - 'Page_4_Heading' => 'Create the Settings File', - 'Page_4_Text' => 'Due to security concerns (Yeah, we\'re fairly paranoid -go figure), this program will not attempt to create or modify the settings file. Instead, we ask you to create it yourself, via FTP or a control panel file manager, name it "auto-config.inc.php", and paste the following text into the file:', - 'NAWS_Export_Spreadsheet_Optional' => 'NAWS Export Spreadsheet (Optional): ', - 'NAWS_Export_Spreadsheet_Initially_Publish' => 'Initialize imported meetings to \'published\': ', - 'DefaultPasswordLength' => 10, - 'DefaultMeetingCount' => 10, - 'DefaultChangeDepth' => 5, - 'DefaultDistanceUnits' => 'mi', - 'DefaultDurationTime' => '01:30:00', - 'DurationTextInitialText' => 'N.A. Meetings are usually 90 minutes long (an hour and a half), unless otherwise indicated.', - 'time_format' => 'g:i A', - 'change_date_format' => 'g:i A, n/j/Y', - 'BannerTextInitialText' => 'Administration Login', - 'TitleTextInitialText' => 'Basic Meeting List Toolbox Administration', - 'DefaultRegionBias' => 'us', - 'search_spec_map_center' => array ( 'longitude' => -118.563659, 'latitude' => 34.235918, 'zoom' => 6 ), - 'DistanceChoices' => array ( 2, 5, 10, 20, 50 ), - 'HistoryChoices' => array ( 1, 2, 3, 5, 8, 10, 15 ), - 'PW_LengthChices' => array ( 6, 8, 10, 12, 16 ), - 'ServerAdminDefaultLogin' => 'serveradmin', - - 'Explanatory_Text_1_Initial_Intro' => 'This install wizard will guide you through the process of creating an initial database, as well as a configuration file. In the final step, we will create a settings file, and initialize an empty database.', - 'Explanatory_Text_1_DB_Intro' => 'The first thing that you need to do, is create a new, EMPTY database, and a database user that has full access to that database. This is usually done via your Web site Control Panel. Once you have created the database, you need to enter the information about that database into the text items on this page.', - - 'Explanatory_Text_2_Region_Bias_Intro' => 'The "Region Bias" is a code that is sent to Google when a location search is done, and can help Google to make sense of ambiguous search queries.', - - 'Explanatory_Text_3_Server_Admin_Intro' => 'The Server Administrator is the main user for the server. It is the only account that can create new users and Service bodies, and is very powerful. You should create a login ID and a non-trivial password for this account. You\'ll be able to modify the other aspects of the account on the main server, once the database has been set up.', - 'Explanatory_Text_3_Misc_Intro' => 'These are various settings that affect how the root server behaves and appears.', - - 'Explanatory_Text_4_Main_Intro' => 'If you have entered the database information, provided a valid Google Maps API Key, and specified the login information for the Server Administrator, then you can initialize the root server here. Remember that the database must be COMPLETELY EMPTY of BMLT Root Server tables for this server (It can have tables for other servers or services).', - 'Explanatory_Text_4_NAWS_Export' => 'Optionally, you can import the meetings from a NAWS export spreadsheet. Uncheck the box to initialize them to \'unpublished\'. (This is useful if many of the new meetings will need to be edited or deleted, and you don\'t want them showing up in the meantime.)', - 'Explanatory_Text_4_File_Intro' => 'The text in the box below is the PHP source code for the main settings file. You will need to create a file on the server with this text in it. The file is at the same level as the main server directory for the root server.', - 'Explanatory_Text_4_File_Extra' => 'You also need to make sure that the file permissions are restricted (chmod 0644). This prevents the file from being written, and the root server will not run unless the file has the correct permissions.', - 'Page_4_PathInfo' => 'The file needs to be placed as %s/auto-config.inc.php, which is where your %s directory is. After the file has been created and you have put the above text into it, you should execute the following command to make sure that the permissions are correct:', - 'Page_4_Final' => 'Once all this is complete, refresh this page, and you should see the root server login page.', - 'FormatLangNamesLabel' => 'Enter extra languages in format code1:name1 (example "fa:farsi ru:russian"):', - ); diff --git a/src/legacy/local_server/server_admin/lang/de/name.txt b/src/legacy/local_server/server_admin/lang/de/name.txt deleted file mode 100644 index 176e5370b..000000000 --- a/src/legacy/local_server/server_admin/lang/de/name.txt +++ /dev/null @@ -1 +0,0 @@ -Deutsch \ No newline at end of file diff --git a/src/legacy/local_server/server_admin/lang/de/server_admin_strings.inc.php b/src/legacy/local_server/server_admin/lang/de/server_admin_strings.inc.php deleted file mode 100644 index 25a7140d5..000000000 --- a/src/legacy/local_server/server_admin/lang/de/server_admin_strings.inc.php +++ /dev/null @@ -1,489 +0,0 @@ -. */ - -defined('BMLT_EXEC') or die('Cannot Execute Directly'); // Makes sure that this file is in the correct context. - -$comdef_server_admin_strings = array( - 'server_admin_disclosure' => 'Server Administration', - 'server_admin_naws_spreadsheet_label' => 'Updated World Committee Codes Spreadsheet', - 'update_world_ids_button_text' => 'Update World Committee Codes', - 'update_world_ids_from_spreadsheet_dropdown_text' => 'Update World Committee Codes (Group IDs from NAWS) from NAWS Spreadsheet', - 'server_admin_error_no_world_ids_updated' => 'No World IDs were updated. This could be because your user does not have permission to update the submitted meetings.', - 'server_admin_error_required_spreadsheet_column' => 'Required column does not exist in the spreadsheet: ', - 'server_admin_error_bmlt_id_not_integer' => 'The provided bmlt_id is not an integer: ', - 'server_admin_error_could_not_create_reader' => 'Could not create reader for file: ', - 'server_admin_error_no_files_uploaded' => 'No files were uploaded.', - 'server_admin_error_service_bodies_already_exist' => 'Service bodies with the following World IDs already exist: ', - 'server_admin_error_meetings_already_exist' => 'Meetings with the following World IDs already exist: ', - 'server_admin_ui_num_meetings_updated' => 'Number of meetings updated: ', - 'server_admin_ui_num_meetings_not_updated' => 'Number of meetings that did not need updating: ', - 'server_admin_ui_warning' => 'WARNING', - 'server_admin_ui_errors' => 'Error(s)', - 'server_admin_ui_deleted_meetings_marked' => 'Number of deleted meetings marked so that they won\'t appear in future NAWS exports: ', - 'server_admin_ui_problem_meetings' => 'meetings were found in the spreadsheet that couldn\'t be updated. Problem meeting IDs: ', - 'server_admin_ui_service_bodies_created' => 'Service bodies created: ', - 'server_admin_ui_meetings_created' => 'Meetings created: ', - 'server_admin_ui_users_created' => 'Users created: ', - 'server_admin_ui_refresh_ui_text' => 'Sign out and then sign in again to see the new service bodies, users, and meetings.', - 'import_service_bodies_and_meetings_button_text' => 'Import Service Bodies and Meetings', - 'import_service_bodies_and_meetings_dropdown_text' => 'Import Service Bodies and Meetings from NAWS Export', - 'server_admin_naws_import_spreadsheet_label' => 'NAWS Import Spreadsheet:', - 'server_admin_naws_import_initially_publish' => 'Initialize imported meetings to \'published\': ', - 'server_admin_naws_import_explanation' => 'Uncheck the box to initialize imported meetings to \'unpublished\'. (This is useful if many of the new meetings will need to be edited or deleted, and you don\'t want them showing up in the meantime.)', - 'account_disclosure' => 'Mein Account', - 'account_name_label' => 'Mein Account Name:', - 'account_login_label' => 'Mein Login:', - 'account_type_label' => 'Ich bin ein:', - 'account_type_1' => 'Server Administrator', - 'account_type_2' => 'Service Body Administrator', - 'ServerMapsURL' => 'http://maps.googleapis.com/maps/api/geocode/xml?address=##SEARCH_STRING##&sensor=false', - 'account_type_4' => 'Pathetic Luser Who Shouldn\'t Even Have Access to This Page -The Author of the Software Pooched it BAD!', - 'account_type_5' => 'Service Body Observer', - 'change_password_label' => 'Mein Passwort ändern in:', - 'change_password_default_text' => 'Leave This Alone If You Don\'t Want To Change Your Password', - 'account_email_label' => 'Meine E-Mailadresse:', - 'email_address_default_text' => 'Trage eine E-Mailadresse ein', - 'account_description_label' => 'Meine Beschreibung:', - 'account_description_default_text' => 'Trage eine Beschreibung ein', - 'account_change_button_text' => 'Account Einstellungen ändern', - 'account_change_fader_success_text' => 'Die Account Information wurde erfolgreich geändert', - 'account_change_fader_failure_text' => 'Die Account Information wurde nicht geändert', - 'meeting_editor_disclosure' => 'Meetings bearbeiten', - 'meeting_editor_already_editing_confirm' => 'Du bearbeitest gerade ein anderes Meeting. Möchtest du alle Änderungen in diesem Meeting verlieren?', - 'meeting_change_fader_success_text' => 'Das Meeting wurde erfolgreich geändert', - 'meeting_change_fader_failure_text' => 'Das Meeting wurde nicht geändert', - 'meeting_change_fader_success_delete_text' => 'Das Meeting wurde erfolgreich gelöscht', - 'meeting_change_fader_fail_delete_text' => 'Das Meeting wurde nicht gelöscht', - 'meeting_change_fader_success_add_text' => 'Das neue Meeting wurde erfolgreich hinzugefügt', - 'meeting_change_fader_fail_add_text' => 'Das neue Meeting wurde nicht hinzugefügt', - 'meeting_text_input_label' => 'Suche nach Text:', - 'access_service_body_label' => 'Ich habe Zugriff zu:', - 'meeting_text_input_default_text' => 'Füge Suchtext ein', - 'meeting_text_location_label' => 'Dies ist ein Ort oder eine PLZ', - 'meeting_search_weekdays_label' => 'Suche nach ausgewählten Wochentagen:', - 'meeting_search_weekdays_names' => array('Alle', 'Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag'), - 'meeting_search_service_bodies_label' => 'Suche nach ausgewählten Service Bodies:', - 'meeting_search_start_time_label' => 'Suche nach Meetings-Anfangszeit:', - 'meeting_search_start_time_all_label' => 'Jede Zeit', - 'meeting_search_start_time_morn_label' => 'Morgen', - 'meeting_search_start_time_aft_label' => 'Nachmittag', - 'meeting_search_start_time_eve_label' => 'Abend', - 'meeting_search_no_results_text' => 'Keine Meetings gefunden', - 'meeting_editor_tab_specifier_text' => 'Suche nach Meetings', - 'meeting_editor_tab_editor_text' => 'Meetings bearbeiten oder erstellen', - 'meeting_editor_create_new_text' => 'Erstelle ein neues Meeting', - 'meeting_editor_location_map_link' => 'Ort auf Karte', - 'meeting_editor_screen_match_ll_button' => 'Setze Koordinaten der Karte auf diese Adresse', - 'meeting_editor_screen_default_text_prompt' => 'Trage einen Text oder eine Zahl ein', - 'meeting_is_published' => 'Meeting ist veröffentlicht', - 'meeting_unpublished_note' => 'Note: Unpublishing a meeting indicates a temporary closure. If this meeting has closed permanently, please delete it.', - 'meeting_editor_screen_meeting_name_label' => 'Meetings-Name:', - 'meeting_editor_screen_meeting_name_prompt' => 'Trage einen Meetings-Namen ein', - 'meeting_editor_screen_meeting_weekday_label' => 'Wochentag:', - 'meeting_editor_screen_meeting_start_label' => 'Meetings-Anfangszeit:', - 'meeting_editor_screen_meeting_time_zone_label' => 'Meeting Time Zone:', - 'meeting_editor_screen_meeting_am_label' => 'AM', - 'meeting_editor_screen_meeting_pm_label' => 'PM', - 'meeting_editor_screen_meeting_noon_label' => '12:00 Uhr', - 'meeting_editor_screen_meeting_midnight_label' => '24:00 Uhr', - 'meeting_editor_screen_meeting_duration_label' => 'Dauer:', - 'meeting_editor_screen_meeting_oe_label' => 'Ende offen', - 'meeting_editor_screen_meeting_cc_label' => 'World Service Committee Code:', - 'meeting_editor_screen_meeting_cc_advice' => 'Normally leave this field alone (see documentation).', // TODO: translate - 'meeting_editor_screen_meeting_contact_label' => 'Meetings E-Mail Kontakt:', - 'meeting_editor_screen_meeting_contact_prompt' => 'Trage eine E-Mail for einen Kontakt nur für dieses Meeting ein', - 'meeting_editor_screen_meeting_sb_label' => 'Service Body:', - 'meeting_editor_screen_meeting_sb_default_value' => 'Kein Service Body ausgewählt', - 'meeting_editor_screen_meeting_longitude_label' => 'Longitude:', - 'meeting_editor_screen_meeting_longitude_prompt' => 'Trage einen Längengrad ein', - 'meeting_editor_screen_meeting_latitude_label' => 'Breitengrad:', - 'meeting_editor_screen_meeting_latitude_prompt' => 'Trage einen Breitengrad ein', - 'meeting_editor_screen_meeting_location_label' => 'Institution:', - 'meeting_editor_screen_meeting_location_prompt' => 'Trage einen Institutions-Namen ein (Wie einen Gebäudenamen)', - 'meeting_editor_screen_meeting_info_label' => 'Zusätzliche Informationen:', - 'meeting_editor_screen_meeting_info_prompt' => 'Trage zusätzliche Location Informationen ein', - 'meeting_editor_screen_meeting_street_label' => 'Straße:', - 'meeting_editor_screen_meeting_street_prompt' => 'Trage eine Straße ein', - 'meeting_editor_screen_meeting_neighborhood_label' => 'Nachbarschaft:', - 'meeting_editor_screen_meeting_neighborhood_prompt' => 'Trage eine Nachbarschaft ein (keinen Stadtteil oder Stadtbezirk)', - 'meeting_editor_screen_meeting_borough_label' => 'Stadtteil:', - 'meeting_editor_screen_meeting_borough_prompt' => 'Trage einen Stadtteil oder Stadtbezirk ein (keine Nachbarschaft)', - 'meeting_editor_screen_meeting_city_label' => 'Stadt:', - 'meeting_editor_screen_meeting_city_prompt' => 'Trage eine Stadt ein (Keine Nation oder Stadtbezirk)', - 'meeting_editor_screen_meeting_county_label' => 'Land:', - 'meeting_editor_screen_meeting_county_prompt' => 'Trage ein Land ein', - 'meeting_editor_screen_meeting_state_label' => 'Bundesstaat/Bundesland:', - 'meeting_editor_screen_meeting_state_prompt' => 'Trage ein Bundesstaat/Bundesland ein', - 'meeting_editor_screen_meeting_zip_label' => 'Postleitzahl:', - 'meeting_editor_screen_meeting_zip_prompt' => 'Trage eine Postleitzahl ein', - 'meeting_editor_screen_meeting_nation_label' => 'Nation:', - 'meeting_editor_screen_meeting_nation_prompt' => 'Trage eine Nation ein', - 'meeting_editor_screen_meeting_comments_label' => 'Comments:', - 'meeting_editor_screen_meeting_train_lines_label' => 'Train Lines:', - 'meeting_editor_screen_meeting_bus_lines_label' => 'Bus Lines:', - 'meeting_editor_screen_meeting_phone_meeting_number_label' => 'Phone Meeting Dial-in Number:', - 'meeting_editor_screen_meeting_phone_meeting_number_prompt' => 'Enter the dial-in number for a phone or virtual meeting', - 'meeting_editor_screen_meeting_virtual_meeting_link_label' => 'Virtual Meeting Link:', - 'meeting_editor_screen_meeting_virtual_meeting_link_prompt' => 'Enter the link for a virtual meeting', - 'meeting_editor_screen_meeting_virtual_meeting_additional_info_label' => 'Virtuelles Meeting - zusätzliche Informationen:', - 'meeting_editor_screen_meeting_virtual_meeting_additional_info_prompt' => 'Enter any additional information for joining the virtual meeting, including directly from the app. For example, if the meeting uses Zoom, "Zoom ID: 456 033 8613, Passcode: 1953" would be appropriate.', - 'meeting_editor_screen_meeting_venue_type' => 'Venue Type:', - 'meeting_editor_screen_meeting_venue_type_inperson' => 'In-Person', - 'meeting_editor_screen_meeting_venue_type_virtual' => 'Virtual', - 'meeting_editor_screen_meeting_venue_type_virtualTC' => 'Virtual (temporarily replacing an in-person)', - 'meeting_editor_screen_meeting_venue_type_hybrid' => 'Hybrid (both in-person and virtual)', - 'meeting_editor_screen_meeting_venue_type_validation' => 'You must select a venue type.', - 'meeting_editor_screen_meeting_virtual_info_missing' => 'Virtual or hybrid meetings must have a Virtual Meeting Link, a Phone Meeting Dial-in Number, or Virtual Meeting Additional Information', - 'meeting_editor_screen_meeting_location_warning' => 'Meeting should have a location (at least a city/town and state/province, or a zip/postal code).', - 'meeting_editor_screen_meeting_address_warning' => 'In-person or hybrid meetings should have a street address.', - 'meeting_editor_screen_meeting_url_validation' => 'Virtual Meeting Link is not a valid URL.', - 'meeting_editor_screen_meeting_url_or_phone_warning' => 'Virtual or hybrid meetings should have either a Virtual Meeting Link or a Phone Meeting Dial-in Number', - 'meeting_editor_screen_meeting_additional_warning' => 'Please also fill in Virtual Meeting Additional Information if there is a Virtual Meeting Link.', - 'meeting_editor_screen_in_person_virtual_info_warning' => 'In-person meetings shouldn\'t have any virtual meeting information.', - 'meeting_editor_screen_meeting_virtual_location_info_warning' => 'Virtual meetings shouldn\'t have a location name or address.', - 'meeting_editor_screen_meeting_validation_warning' => 'There are warnings. Are you sure you want to save anyway? If not, press \'cancel\' and go to the Location tab to see the warnings in place and address them.', - 'meeting_editor_screen_meeting_validation_failed' => 'Unable to save due to input errors. Please go to the Location tab to address them, and then retry saving. Errors: ', - 'meeting_editor_screen_meeting_validation_warnings' => 'Input warnings shown on the Location tab: ', - 'meeting_editor_screen_meeting_contact_name_1_label' => 'Contact 1 Name:', - 'meeting_editor_screen_meeting_contact_email_1_label' => 'Contact 1 Email:', - 'meeting_editor_screen_meeting_contact_phone_1_label' => 'Contact 1 Phone:', - 'meeting_editor_screen_meeting_contact_name_2_label' => 'Contact 2 Name:', - 'meeting_editor_screen_meeting_contact_email_2_label' => 'Contact 2 Email:', - 'meeting_editor_screen_meeting_contact_phone_2_label' => 'Contact 2 Phone:', - 'meeting_editor_screen_meeting_publish_search_prompt' => 'Suche nach:', - 'meeting_editor_screen_meeting_publish_search_pub' => 'nur veröfentlichte Meetings', - 'meeting_editor_screen_meeting_publish_search_unpub' => 'nur unveröfentlichte Meetings', - 'meeting_editor_screen_meeting_visibility_advice' => 'Dies wird in normalen Suchen nie angezeigt.', - 'meeting_editor_screen_meeting_publish_search_all' => 'Alle Meetings', - 'meeting_editor_screen_meeting_create_button' => 'Erstelle ein neues Meeting', - 'meeting_editor_screen_delete_button' => 'Lösche dieses Meeting', - 'meeting_editor_screen_delete_button_confirm' => 'Bist du sicher, dass du dieses Meeting löschen möchtest?', - 'meeting_editor_screen_cancel_button' => 'abbrechen', - 'logout' => 'Abmelden', - 'meeting_editor_screen_cancel_confirm' => 'Bist du sicher, dass du die Bearbeitung abbrechen möchtest und alle Änderungen verlieren möchtest?', - 'meeting_lookup_failed' => 'Die Suche nach der Adresse schlug fehl.', - 'meeting_lookup_failed_not_enough_address_info' => 'Dies ist keine gültige Adresse für eine Suche.', - 'meeting_create_button_name' => 'Speichere dies als ein neues Meeting', - 'meeting_saved_as_a_copy' => 'Speichere dies als eine Kopie (erstellt ein neues Meeting)', - 'meeting_save_buttonName' => 'Speichere die Änderungen an diesem Meeting', - 'meeting_editor_tab_bar_basic_tab_text' => 'Basic', - 'meeting_editor_tab_bar_location_tab_text' => 'Institution', - 'meeting_editor_tab_bar_format_tab_text' => 'Format', - 'meeting_editor_tab_bar_other_tab_text' => 'Sonstiges', - 'meeting_editor_tab_bar_history_tab_text' => 'History', - 'meeting_editor_result_count_format' => '%d Meetings gefunden', - 'meeting_id_label' => 'Meeting ID:', - 'meeting_editor_default_zoom' => '13', - 'meeting_editor_default_weekday' => '2', - 'meeting_editor_default_start_time' => '20:30:00', - 'login_banner' => 'Basic Meeting List Toolbox', - 'login_underbanner' => 'Root Server Administration Console', - 'login' => 'Login ID', - 'password' => 'Passwort', - 'button' => 'Log In', - 'cookie' => 'Man muss Cookies erlauben um diesen Server zu verwalten.', - 'noscript' => 'Man kann diese Seite nicht ohne JavaScript verwalten.', - 'title' => 'Bitte zum Verwalten des Servers einloggen.', - 'edit_Meeting_object_not_found' => 'ERROR: Dieses Meeting wurde nicht gefunden.', - 'edit_Meeting_object_not_changed' => 'ERROR: Dieses Meeting wurde nicht geändert.', - 'edit_Meeting_auth_failure' => 'Du hast keine Berechtigung, dieses Meeting zu bearbeiten.', - 'not_auth_1' => 'NOT AUTHORIZED', - 'not_auth_2' => 'Du hast keine Berechtigung, diesen Server zu verwalten.', - 'not_auth_3' => 'Es gab ein Problem mit Benutzernamen oder Passwort.', - 'email_format_bad' => 'Das Format der eingefügten E-Mailadresse ist nicht richtig.', - 'history_header_format' => '
%sby %s
', - 'history_no_history_available_text' => '

No History Available For This Meeting

', - 'service_body_editor_disclosure' => 'Service Body Administration', - 'service_body_change_fader_success_text' => 'Der Service Body wurde erfolgreich geändert', - 'service_body_change_fader_fail_text' => 'Die Änderung des Service Body schlug fehl', - 'service_body_editor_screen_sb_id_label' => 'ID:', - 'service_body_editor_screen_sb_name_label' => 'Name:', - 'service_body_name_default_prompt_text' => 'Trage den Namen dieses Service Body ein', - 'service_body_parent_popup_label' => 'Service Body Parent:', - 'service_body_parent_popup_no_parent_option' => 'No Parent (Top-Level)', - 'service_body_editor_screen_sb_admin_user_label' => 'Primary Admin:', - 'service_body_editor_screen_sb_admin_description_label' => 'Beschreibung:', - 'service_body_description_default_prompt_text' => 'Trage eine Beschreibung dieses Service Body ein', - 'service_body_editor_screen_sb_admin_email_label' => 'Contact Email:', - 'service_body_email_default_prompt_text' => 'Trage eine Kontakt-E-Mailadresse für deisen Service Body ein', - 'service_body_editor_screen_sb_admin_uri_label' => 'Web Site URL:', - 'service_body_uri_default_prompt_text' => 'Trage eine Web Site URL für diesen Service Body ein', - 'service_body_editor_screen_sb_admin_full_editor_label' => 'Volle Meetingslisten Bearbeiter:', - 'service_body_editor_screen_sb_admin_full_editor_desc' => 'Diese Benutzer können alle Meetings in diesem Service Body bearbeiten.', - 'service_body_editor_screen_sb_admin_editor_label' => 'Basic Meeting List Bearbeiter:', - 'service_body_editor_screen_sb_admin_editor_desc' => 'Diese Benutzer können alle Meetings in diesem Service Body bearbeiten, aber nur, wenn sie unveröffentlicht sind.', - 'service_body_editor_screen_sb_admin_observer_label' => 'Beobachter:', - 'service_body_editor_screen_sb_admin_observer_desc' => 'Diese Benutzer können versteckte Informationen sehen (wie E-Mailadressen), aber können nichts bearbeiten.', - 'service_body_dirty_confirm_text' => 'Du hast den Service Body verändert. möchtest due diese Änderungen verlieren?', - 'service_body_save_button' => 'Speichere diese Änderungen am Service Body', - 'service_body_create_button' => 'Erstelle diesen Service Body', - 'service_body_delete_button' => 'Lösche diesen Service Body', - 'service_body_delete_perm_checkbox' => 'Lösche diesen Service Body dauerhaft', - 'service_body_delete_button_confirm' => 'Are you sure that you want to delete this Service body? Make sure that all meetings are either removed or transferred to another service body before performing this function.', - 'service_body_delete_button_confirm_perm' => 'Dieser Service Body wird dauerhaft gelöscht werden!', - 'service_body_change_fader_create_success_text' => 'Der Service Body wurde erfolgreich erstellt', - 'service_body_change_fader_create_fail_text' => 'Das Erstellen des Serice Body schlug fehl', - 'service_body_change_fader_delete_success_text' => 'Der Service Body wurde erfolgreich gelöscht', - 'service_body_change_fader_delete_fail_text' => 'Das Löschen des Serice Body schlug fehl', - 'service_body_change_fader_fail_no_data_text' => 'Das Ändern des Serice Body schlug fehl, weil keine Daten geliefert wurden', - 'service_body_change_fader_fail_cant_find_sb_text' => 'Das Ändern des Serice Body schlug fehl, weil der Service Body nicht gefunden wurde', - 'service_body_change_fader_fail_cant_update_text' => 'Das Ändern des Serice Body schlug fehl, weil der Service Body nicht upgedatet wurde', - 'service_body_change_fader_fail_bad_hierarchy' => 'Das Ändern des Serice Body schlug fehl, weil der gewählte Eigentümer Service Body unter diesem Service Body ist, und nicht benutzt werden kann', - 'service_body_cancel_button' => 'Zurücksetzen auf Ursprung', - 'service_body_editor_type_label' => 'Service Body Type:', - 'service_body_editor_type_c_comdef_service_body__GRP__' => 'Gruppe', - 'service_body_editor_type_c_comdef_service_body__COP__' => 'Co-Op', - 'service_body_editor_type_c_comdef_service_body__ASC__' => 'Gebiets Service Kommitee', - 'service_body_editor_type_c_comdef_service_body__RSC__' => 'Regionale Service Konferenz', - 'service_body_editor_type_c_comdef_service_body__WSC__' => 'World Service Conference', - 'service_body_editor_type_c_comdef_service_body__MAS__' => 'Metro Area', - 'service_body_editor_type_c_comdef_service_body__ZFM__' => 'Zonal Forum', - 'service_body_editor_type_c_comdef_service_body__GSU__' => 'Group Service Unit', - 'service_body_editor_type_c_comdef_service_body__LSU__' => 'Local Service Unit', - 'service_body_editor_screen_helpline_label' => 'Helpline:', - 'service_body_editor_screen_helpline_prompt' => 'Enter The Helpline Telephone Number', - 'service_body_editor_uri_naws_format_text' => 'Get The Meetings For This Service Body As A NAWS-Compatible File', - 'edit_Meeting_meeting_id' => 'Meeting ID:', - 'service_body_editor_create_new_sb_option' => 'Erstelle einen neuen Service Body', - 'service_body_editor_screen_world_cc_label' => 'World Service Committee Code:', - 'service_body_editor_screen_world_cc_prompt' => 'Trage einen Service Committee Code ein', - 'user_editor_disclosure' => 'Benutzerverwaltung', - 'user_editor_create_new_user_option' => 'CErstelle einen neuen Benutzer', - 'user_editor_screen_sb_id_label' => 'ID:', - 'user_editor_account_login_label' => 'Benutzer Login:', - 'user_editor_login_default_text' => 'Trage den Benutzer Login ein', - 'user_editor_account_type_label' => 'Benutzer ist ein:', - 'user_editor_user_owner_label' => 'Owned By: ', // TODO translate - 'user_editor_account_type_1' => 'Server Administrator', - 'user_editor_account_type_2' => 'Service Body Administrator', - 'user_editor_account_type_3' => 'Service Body Editor', - 'user_editor_account_type_5' => 'Service Body Observer', - 'user_editor_account_type_4' => 'Deaktivierter Benutzer', - 'user_editor_account_name_label' => 'Benutzername:', - 'user_editor_name_default_text' => 'Trage den Benutzernamen ein', - 'user_editor_account_description_label' => 'Beschreibung:', - 'user_editor_description_default_text' => 'Trage eine Benutzerbeschreibung ein', - 'user_editor_account_email_label' => 'E-Mailadresse:', - 'user_editor_email_default_text' => 'Trage die Benutzer-E-Mailadresse ein', - 'user_change_fader_success_text' => 'Der Benutzer wurde erfolgreich geändert', - 'user_change_fader_fail_text' => 'Das Ändern des Benutzers schlug fehl', - 'user_change_fader_create_success_text' => 'Der Benutzer wurde erfolgreich erstellt', - 'user_change_fader_create_fail_text' => 'Das Erstellen des Benutzers schlug fehl', - 'user_change_fader_delete_success_text' => 'Der Benutzer wurde erfolgreich gelöscht', - 'user_change_fader_delete_fail_text' => 'Das Löschen des Benutzers schlug fehl', - 'user_save_button' => 'Änderungen an diesem Benutzer speichern', - 'user_create_button' => 'Erstelle diesen neuen Benutzer', - 'user_cancel_button' => 'Zurücksetzen auf Ursprung', - 'user_delete_button' => 'Lösche diesen Benutzer', - 'user_delete_perm_checkbox' => 'Lösche diesen Benutzer dauerhaft', - 'user_password_label' => 'Ändere das Passwort zu:', - 'user_new_password_label' => 'Setze das Passwort zu:', - 'user_password_default_text' => 'Lass das frei, wenn du das Psswort nicht ändern willst', - 'user_new_password_default_text' => 'Du must ein Passwort für einen neuen Benutzer eintragen', - 'user_dirty_confirm_text' => 'Du hast den Benutzer verändert. möchtest due diese Änderungen verlieren?', - 'user_delete_button_confirm' => 'Bist du sicher, dass du diesen Benutzer löschen möchtest?', - 'user_delete_button_confirm_perm' => 'Dieser Benutzer wird dauerhaft gelöscht werden!', - 'user_create_password_alert_text' => 'Neue Benutzer brauchen ein Passwort. Du hast noch kein Passwort eingetragen.', - 'user_change_fader_fail_cant_find_sb_text' => 'Das Ändern des Benutzers schlug fehl, weil der Benutzer nicht gefunden wurde', - 'user_change_fader_fail_cant_update_text' => 'Das Ändern des Benutzers schlug fehl, weil der Benutzer nicht upgedatet wurde', - 'format_editor_disclosure' => 'Format Verwaltung', - 'format_change_fader_change_success_text' => 'Das Format wurde erfolgreich geändert', - 'format_change_fader_change_fail_text' => 'Das Ändern des Formats schlug fehl', - 'format_change_fader_create_success_text' => 'Das Format wurde erfolgreich erstellt', - 'format_change_fader_create_fail_text' => 'Das Erstellen des Formats schlug fehl', - 'format_change_fader_delete_success_text' => 'Das Format wurde erfolgreich gelöscht', - 'format_change_fader_delete_fail_text' => 'Das Löschen des Formats schlug fehl', - 'format_change_fader_fail_no_data_text' => 'Das Ändern des Formats schlug fehl, weil keine Daten geliefert wurden', - 'format_change_fader_fail_cant_find_sb_text' => 'Das Ändern des Formatss schlug fehl, weil das Format nicht gefunden wurde', - 'format_change_fader_fail_cant_update_text' => 'Das Ändern des Formats schlug fehl, weil deas Format nicht upgedatet wurde', - 'format_editor_name_default_text' => 'Trage eine kurze Beschreibung ein', - 'format_editor_description_default_text' => 'Trage eine detailiertere Beschreibung ein', - 'format_editor_create_format_button_text' => 'Erstelle ein neues Format', - 'format_editor_cancel_create_format_button_text' => 'abbrechen', - 'format_editor_create_this_format_button_text' => 'Erstelle dieses Format', - 'format_editor_change_format_button_text' => 'Ändere dieses Format', - 'format_editor_delete_format_button_text' => 'Lösche dieses Format', - 'format_editor_reset_format_button_text' => 'Zurücksetzen auf Ursprung', - 'need_refresh_message_fader_text' => 'Vor Benutzung dieses Bereiches sollte diese Seite neu geladen werden', - 'need_refresh_message_alert_text' => 'Weil Änderungen in der Service Body Verwaltung, Benutzerverwaltung oder Format Verwaltung vorgenommen wurden, ist die Information, die in diesem Bereich dargestellt wird, nicht mehr akkurat, also muss die Seite neu geladen werden. Der einfachste Weg dies zu tun ist sich abzumelden und sich wieder anzumelden.', - 'format_editor_delete_button_confirm' => 'Bist du sicher, dass du dieses Format löschen willst?', - 'format_editor_delete_button_confirm_perm' => 'Dieses Format wird dauerhaft gelöscht werden!', - 'format_editor_missing_key' => 'This format should have an entry for every language (at least a key).', // TODO: translate - 'format_editor_reserved_key' => 'This key is reserved for a venue type format - please use something different.', // TODO: translate - 'min_password_length_string' => 'Das Passwort ist zu kurz! Es muss mindestens %d zeichen betragen!', - 'AJAX_Auth_Failure' => 'Authorisation fehlgeschlagen für diese Operation. Es kann sein, dass ein Problem mit der Serverkonfiguration besteht.', - 'Maps_API_Key_Warning' => 'There is a problem with the Google Maps API Key.', // TODO translate - 'Observer_Link_Text' => 'Meeting Browser', - 'Data_Transfer_Link_Text' => 'Import Meeting Data (WARNING: Replaces Current Data!)', - 'MapsURL' => 'http://maps.google.com/maps?q=##LAT##,##LONG##+(##NAME##)&ll=##LAT##,##LONG##', - 'hidden_value' => 'Cannot Display Data -Unauthorized', - 'Value_Prompts' => array( - 'id_bigint' => 'Meeting ID', - 'worldid_mixed' => 'World Services ID', - 'service_body' => 'Service Body', - 'service_bodies' => 'Service Bodies', - 'weekdays' => 'Weekdays', - 'weekday' => 'Meeting Gathers Every', - 'start_time' => 'Meeting Starts at', - 'duration_time' => 'Meeting Lasts', - 'location' => 'Location', - 'duration_time_hour' => 'Hour', - 'duration_time_hours' => 'Hours', - 'duration_time_minute' => 'Minute', - 'duration_time_minutes' => 'Minutes', - 'lang_enum' => 'Language', - 'formats' => 'Formats', - 'distance' => 'Distance from Center', - 'generic' => 'NA Meeting', - 'close_title' => 'Close This Meeting Detail Window', - 'close_text' => 'Close Window', - 'map_alt' => 'Map to Meeting', - 'map' => 'Follow This Link for A Map', - 'title_checkbox_unpub_meeting' => 'This meeting is unpublished. It cannot be seen by regular searches.', - 'title_checkbox_copy_meeting' => 'This meeting is a duplicate of another meeting. It is also unpublished. It cannot be seen by regular searches.' - ), - 'world_format_codes_prompt' => 'NAWS Format:', - 'world_format_codes' => array( - '' => 'Keine', - 'OPEN' => 'Offen', - 'CLOSED' => 'Geschlossen', - 'WCHR' => 'Rollstuhlzugang', - 'BEG' => 'Neuankömmling/Newcomer', - 'BT' => 'Basic Text', - 'CAN' => 'Kerzenlicht', - 'CPT' => '12 Konzepte', - 'CW' => 'Kinder willkommen', - 'DISC' => 'Diskussion/Teilen', - 'GL' => 'Schwul/Lesbisch', - 'IP' => 'Thema Faltblätter', - 'IW' => 'Es funktioniert', - 'JFT' => 'Nur für Heute', - 'LC' => 'Thema Living Clean', - 'LIT' => 'Literaturmeeting', - 'M' => 'Männer', - 'MED' => 'Meditation', - 'NS' => 'Non-Smoking', - 'QA' => 'Frage & Antwort', - 'RA' => 'Eingeschränkter Zutritt', - 'S-D' => 'Sprecher / Diskussion', - 'SMOK' => 'Raucher', - 'SPK' => 'Sprecher', - 'STEP' => 'Schritte', - 'SWG' => 'Schritteleitfaden', - 'TOP' => 'Themenmeeting', - 'TRAD' => 'Traditionenmeeting', - 'VAR' => 'Format variatiiert', - 'W' => 'Frauen', - 'Y' => 'Junge Menschen', - 'LANG' => 'Fremdsprache', - 'GP' => 'Guiding Principles', // TODO translate - 'NC' => 'No Children', // TODO translate - 'CH' => 'Closed Holidays', // TODO translate - 'VM' => 'Virtual', // TODO translate - 'HYBR' => 'Virtual and In-person', // TODO translate - 'TC' => 'Temporarily Closed Facility', // TODO translate - 'SPAD' => 'Ein spirituelles Prinzip pro Tag', - ), - 'format_type_prompt' => 'Format Type:', - 'format_type_codes' => array( - '' => 'None', - 'FC1' => 'Meeting Format (Speaker, Book Study, etc.)', - 'FC2' => 'Location Code (Wheelchair Accessible, Limited Parking, etc.)', - 'FC3' => 'Common Needs and Restrictions (Mens Meeting, LGTBQ, No Children, etc.)', - 'O' => 'Attendance by non-addicts (Open, Closed)', - 'LANG' => 'Language', - 'ALERT' => 'Format should be especially prominent (Clean requirement, etc.)', - ), - - 'cookie_monster' => 'Diese Website benutzt ein Cookie, um Ihre bevorzugte Sprache zu speichern.', - 'main_prompts' => array( - 'id_bigint' => 'ID', - 'worldid_mixed' => 'World ID', - 'shared_group_id_bigint' => 'Unused', - 'service_body_bigint' => 'Service Body ID', - 'weekday_tinyint' => 'Wochentag', - 'venue_type' => 'Venue Type', - 'start_time' => 'Start Zeit', - 'duration_time' => 'Dauer', - 'time_zone' => 'Time Zone', - 'formats' => 'Formate', - 'lang_enum' => 'Sprache', - 'longitude' => 'Längengrad', - 'latitude' => 'Breitengrad', - 'published' => 'veröffentlicht', - 'email_contact' => 'E-Mail Kontakt', - ), - 'check_all' => 'Check All', - 'uncheck_all' => 'Uncheck All', - 'automatically_calculated_on_save' => 'Automatically calculated on save.' -); - -$email_contact_strings = array( - 'meeting_contact_form_subject_format' => "[MEETING LIST CONTACT] %s", - 'meeting_contact_message_format' => "%s\n--\nDiese Nachricht betrifft das Meeting namens\"%s\", dzss sich trifft um %s, immer %s.\nBrowser Link: %s\nEdit Link: %s\nEs wurde direkt vom Webserver der Meetingliste gesendet, und der Absender kennt Ihre E-Mail-Adresse nicht.\nBitte beachten Sie, dass Ihre E-Mail-Adresse beim Antworten angezeigt wird.\nWenn Sie \"Reply All\" verwenden, Wenn es mehrere E-Mail-Empfänger gibt, könnten Sie die E-Mail-Adressen anderer Personen anzeigen.\nBitte respektieren Sie die Privatsphäre und Anonymität der Menschen einschließlich des ursprünglichen Absenders dieser Nachricht." -); - -$change_type_strings = array( - '__THE_MEETING_WAS_CHANGED__' => 'Das Meeting wurde geändert.', - '__THE_MEETING_WAS_CREATED__' => 'Das Meeting wurde erstellt.', - '__THE_MEETING_WAS_DELETED__' => 'Das Meeting wurde gelöscht.', - '__THE_MEETING_WAS_ROLLED_BACK__' => 'Das Meeting wurde auf die vorherige Version zurück gesetzt.', - - '__THE_FORMAT_WAS_CHANGED__' => 'Das Format wurde geändert.', - '__THE_FORMAT_WAS_CREATED__' => 'Das Format wurde erstellt.', - '__THE_FORMAT_WAS_DELETED__' => 'Das Format wurde gelöscht.', - '__THE_FORMAT_WAS_ROLLED_BACK__' => 'Das Format wurde auf die vorherige Version zurück gesetzt.', - - '__THE_SERVICE_BODY_WAS_CHANGED__' => 'Der service body wurde geändert.', - '__THE_SERVICE_BODY_WAS_CREATED__' => 'Der service body wurde erstellt.', - '__THE_SERVICE_BODY_WAS_DELETED__' => 'Der service body wurde gelöscht.', - '__THE_SERVICE_BODY_WAS_ROLLED_BACK__' => 'Der service body wurde auf die vorherige Version zurück gesetzt.', - - '__THE_USER_WAS_CHANGED__' => 'Der Benutzer wurde geändert.', - '__THE_USER_WAS_CREATED__' => 'Der Benutzer wurde erstellt.', - '__THE_USER_WAS_DELETED__' => 'Der Benutzer wurde gelöscht.', - '__THE_USER_WAS_ROLLED_BACK__' => 'Der Benutzer wurde auf die vorherige Version zurück gesetzt.', - - '__BY__' => 'by', - '__FOR__' => 'for' -); - -$detailed_change_strings = array( - 'was_changed_from' => 'was changed from', - 'to' => 'to', - 'was_changed' => 'wurde geändert', - 'was_added_as' => 'wurde hinzugefügt als', - 'was_deleted' => 'wurde gelöscht', - 'was_published' => 'Das Meeting wurde veröffentlicht', - 'was_unpublished' => 'Das Meeting wurde deaktiviert', - 'formats_prompt' => 'Das Meetings-Format', - 'duration_time' => 'Die Meetings-Dauer', - 'start_time' => 'Die Meetings Start-Zeit', - 'longitude' => 'Der Meetings-Längengrad', - 'latitude' => 'Der Meetings-Breitengrad', - 'sb_prompt' => 'Das Meeting änderte seinen Service Body von', - 'id_bigint' => 'Die Meetings-ID', - 'lang_enum' => 'Die Meetings-Sprache', - 'worldid_mixed' => 'Die gemeinsame Group ID', // TODO: translate The World Committee Code - 'weekday_tinyint' => 'Der Tag der Woche, an dem das Meeting stattfindet', - 'non_existent_service_body' => 'Dieser Service Body existiert nicht mehr', -); - -defined('_END_CHANGE_REPORT') or define('_END_CHANGE_REPORT', '.'); diff --git a/src/legacy/local_server/server_admin/lang/dk/data_transfer_strings.php b/src/legacy/local_server/server_admin/lang/dk/data_transfer_strings.php deleted file mode 100644 index aedc985c6..000000000 --- a/src/legacy/local_server/server_admin/lang/dk/data_transfer_strings.php +++ /dev/null @@ -1,45 +0,0 @@ -.*/ - defined('BMLT_EXEC') or die('Cannot Execute Directly'); // Makes sure that this file is in the correct context. - - $comdef_data_transfer_strings = array ( 'key_strings' => array ( 'id_bigint' => 1, - 'worldid_mixed' => 1, - 'shared_group_id_bigint' => 1, - 'service_body_bigint' => 1, - 'weekday_tinyint' => 1, - 'start_time' => 1, - 'duration_time' => 1, - 'formats' => 1, - 'lang_enum' => 1, - 'longitude' => 1, - 'latitude' => 1, - 'published' => 1, - 'email_contact' => 1 - ), - - 'days' => array ( 'Søndag', - 'Mandag', - 'Tirsdag', - 'Onsdag', - 'Torsdag', - 'Fredag', - 'Lørdag' - ), - ); diff --git a/src/legacy/local_server/server_admin/lang/dk/install_wizard_strings.php b/src/legacy/local_server/server_admin/lang/dk/install_wizard_strings.php deleted file mode 100644 index b34b87e15..000000000 --- a/src/legacy/local_server/server_admin/lang/dk/install_wizard_strings.php +++ /dev/null @@ -1,155 +0,0 @@ -.*/ - defined('BMLT_EXEC') or die('Cannot Execute Directly'); // Makes sure that this file is in the correct context. - - global $comdef_install_wizard_strings; - - $comdef_install_wizard_strings = array ( - 'Database_Version_Error' => 'FEJL: Du skal have PHP Version 5.6 eller nyere installeret på denne server!', - 'Database_PDO_Error' => 'FEJL: Du har ikke PHP PDO installeret!', - 'Database_Type_Error' => 'FEJL: Selvom du har PDO, har du ikke installeret databasedrivere!', - 'Database_Type_MySQL_Error' => 'FEJL: Selvom du har PDO, og du har installeret database drivere, er ingen af MySQL (den eneste understøttede driver)!', - 'Database_TestButton_Text' => 'TEST', - 'Database_TestButton_Success' => 'Databaseforbindelsen var vellykket.', - 'Database_TestButton_Fail' => 'Databaseforbindelsen mislykkedes: ', - 'Database_TestButton_Fail2' => 'Databaseforbindelsen mislykkedes, fordi der allerede er en initialiseret database.', - 'Database_Whitespace_Note' => 'Warning: %s has whitespace at the beginning or end.', - - 'AJAX_Handler_DB_Connect_Error' => 'Databaseforbindelsen mislykkedes! Sørg for, at databasen eksisterer, ER HELT TOM, brugeren er oprettet, og den bruger har fuld tilladelse på den tomme database.', - 'AJAX_Handler_DB_Established_Error' => 'Databasen eksisterer allerede, og er blevet oprettet! Du kan ikke bruge denne opsætning til at overskrive en eksisterende database!', - 'AJAX_Handler_DB_Incomplete_Error' => 'Der er ikke nok information til at initialisere databasen!', - - 'NoDatabase_Note_AlreadySet' => 'Der er allerede en eksisterende database, så du kan ikke initialisere en ny.', - 'NoDatabase_Note_PasswordIssue' => 'Du skal oprette en serveradministratorkonto, før databasen kan initialiseres.', - 'NoServerAdmin_Note_AlreadySet' => 'Der findes allerede en eksisterende database, så du kan ikke oprette en serveradministratorkonto (der eksisterer allerede en).', - 'NeedLongerPasswordNote' => 'Denne adgangskode er for kort. Det skal være mindst %d tegn langt.', - - 'Prev_Button' => 'FORRIGE', - 'Next_Button' => 'NÆSTE', - - 'Page_1_Tab' => 'TRIN 1: Database', - 'Page_1_Heading' => 'Indstillinger Database Forbindelse', - 'Page_1_Text' => 'Inden du kan anvende indstillingerne på denne side, skal du oprette en ny FULDSTÆNDIG TOM database og oprette en database bruger, der har fuld brugerrettigheder på den pågældende database.', - - 'Database_Name' => 'Database Navn:', - 'Database_Name_Default_Text' => 'Indsæt et Database Navn', - 'Database_Type' => 'Database Type:', - 'Database_Host' => 'Database Host:', - 'Database_Host_Default_Text' => 'Indsæt en Database Host', - 'Database_Host_Additional_Text' => 'Dette er normalt "localhost."', - 'Table_Prefix' => 'Table Prefix:', - 'Table_Prefix_Default_Text' => 'Indsæt et Table Prefix', - 'Table_Prefix_Additional_Text' => 'Kun for flere root-servere, der deler en database.', - 'Database_User' => 'Database Bruger:', - 'Database_User_Default_Text' => 'Indsæt et Database Bruger Navn', - 'Database_PW' => 'Database Password:', - 'Database_PW_Default_Text' => 'Indsæt et Database Password', - 'Database_PW_Additional_Text' => 'Opret dette som et svært, vanskelig adgangskode. Det har en masse magt, og du behøver aldrig at huske det.', - - 'Maps_API_Key_Warning' => 'ADVARSEL: Der er et problem med API-nøglen til Google Maps.', - 'Maps_API_Key_Not_Set' => 'ADVARSEL: Google Maps API-nøglen er ikke angivet.', - 'Maps_API_Key_Valid' => 'Google Maps API nøgle er gyldig.', - - 'Page_2_Tab' => 'Trin 2: Indstillinger for Google Maps API', - 'Page_2_Heading' => 'Indstillinger for Google Maps API', - 'Page_2_API_Key_Prompt' => 'Enter the Google API Key for Geocoding:', - 'Page_2_API_Key_Set_Button' => 'TESTSØGLE', - 'Page_2_API_Key_Not_Set_Prompt' => 'SÆT API KEY FØRST', - 'Page_2_Text' => 'Når du gemmer et møde, bruger BMLT Root Server API en til Google Maps til at bestemme bredde og længdegrad for mødeadressen. Disse indstillinger er nødvendige for at tillade, at BMLT Root Server kommunikerer med Google Maps API.', - - 'Page_3_Tab' => 'TRIN 3: Serverindstillinger', - 'Page_3_Heading' => 'Indstil forskellige globale serverindstillinger', - 'Page_3_Text' => 'Dette er nogle få indstillinger, der påvirker administrationen og den generelle konfiguration af denne server. De fleste serverindstillinger udføres på selve serveren.', - 'Admin_Login' => 'Login til serveradministrator:', - 'Admin_Login_Default_Text' => 'Indsæt et serveradministrator login', - 'Admin_Login_Additional_Text' => 'Dette er login-streng for serveradministratoren.', - 'Admin_Password' => 'Server Administrator Password:', - 'Admin_Password_Default_Text' => 'Indsæt en serveradministratoradgangskode', - 'Admin_Password_Additional_Text' => 'Sørg for, at dette er et ikke-trivielt kodeord! Det har en masse betydning! (Og Glem det ikke).', - 'ServerAdminName' => 'Server Administrator', - 'ServerAdminDesc' => 'Main Server Administrator', - 'ServerLangLabel' => 'Standard server sprog:', - 'DistanceUnitsLabel' => 'Afstandsenheder:', - 'DistanceUnitsMiles' => 'Miles', - 'DistanceUnitsKM' => 'Kilometer', - 'SearchDepthLabel' => 'Tæthed af møder ved automatisk søgning:', - 'SearchDepthText' => 'Dette er en tilnærmelse af, hvor mange møder der skal findes i det automatiske radiusvalg. Flere møder betyder en større radius.', - 'HistoryDepthLabel' => 'Hvor mange møder ændringer skal gemmes:', - 'HistoryDepthText' => ' Jo længere historie, desto større bliver databasen.', - 'TitleTextLabel' => 'Titel på administrations Knappen:', - 'TitleTextDefaultText' => 'Indsæt en kort titel for redigerings login siden', - 'BannerTextLabel' => 'Hurtig administrator login:', - 'BannerTextDefaultText' => 'Indsæt en kort forespørgsel til login side', - 'RegionBiasLabel' => 'Favorit Region:', - 'PasswordLengthLabel' => 'Minimum adgangskode længde:', - 'PasswordLengthExtraText' => 'Dette vil også påvirke Server Administrator adgangskode, ovenfor.', - 'DefaultClosedStatus' => 'Møder betragtes som "LUKKET" som Udgangspunkt:', - 'DefaultClosedStatusExtraText' => 'Dette påvirker primært eksporten til NAWS.', - 'DurationLabel' => 'Standard Møde Varighed:', - 'DurationHourLabel' => 'Timer', - 'DurationMinutesLabel' => 'Minutter', - 'LanguageSelectorEnableLabel' => 'Vis sprogvalg ved login:', - 'LanguageSelectorEnableExtraText' => 'Hvis du vælger dette, vises en pop op-menu på login-skærmen, så administratorer kan vælge deres sprog.', - 'SemanticAdminLabel' => 'Aktivér semantisk administration:', - 'SemanticAdminExtraText' => 'Hvis ikke markeret, skal al administration ske via Root Server login (Ingen apps).', - 'EmailContactEnableLabel' => 'Tillad e-mail-kontakter fra møder:', - 'EmailContactEnableExtraText' => 'Hvis du vælger dette, vil besøgende kunne sende e-mails fra møde optegnelser.', - 'EmailContactAdminEnableLabel' => 'Inkluder Service Enhed Administrator på disse e-mails:', - 'EmailContactAdminEnableExtraText' => 'Sender kopier af disse e-mails til service enhedens administrator (hvis de ikke er den primære modtager).', - 'EmailContactAllAdminEnableLabel' => 'Medtag alle service enhedsadministratorer på disse e-mails:', - 'EmailContactAllAdminEnableExtraText' => 'Send kopier af disse e-mails til alle relevante Service Enheds Administrators.', - - 'Page_4_Tab' => 'TRIN 4: Gem indstillingerne', - 'Page_4_Heading' => 'Opret indstillingsfilen', - 'Page_4_Text' => 'På grund af sikkerhedsproblemer (Ja, vi er ret paranoid -go figur), vil dette program ikke forsøge at oprette eller ændre indstillingsfilen. I stedet beder vi dig om at oprette det selv, via FTP eller en kontrolpanel filhåndtering, navngiv det "auto-config.inc.php" og indsæt følgende tekst i filen:', - - 'DefaultPasswordLength' => 10, - 'DefaultMeetingCount' => 10, - 'DefaultChangeDepth' => 5, - 'DefaultDistanceUnits' => 'mi', - 'DefaultDurationTime' => '01:30:00', - 'DurationTextInitialText' => 'N.A. Møder er normalt 60 minutter lange (en time), medmindre andet er angivet.', - 'time_format' => 'g:i A', - 'change_date_format' => 'g:i A, n/j/Y', - 'BannerTextInitialText' => 'Administration Login', - 'TitleTextInitialText' => 'Basic Meeting List Toolbox Administration', - 'DefaultRegionBias' => 'us', - 'search_spec_map_center' => array ( 'Længdegrad' => -118.563659, 'Højdegrad' => 34.235918, 'zoom' => 6 ), - 'DistanceChoices' => array ( 2, 5, 10, 20, 50 ), - 'HistoryChoices' => array ( 1, 2, 3, 5, 8, 10, 15 ), - 'PW_LengthChices' => array ( 6, 8, 10, 12, 16 ), - 'ServerAdminDefaultLogin' => 'serveradmin', - - 'Explanatory_Text_1_Initial_Intro' => 'Denne installationsguiden fører dig gennem processen med oprettelse af en startdatabase samt en konfigurationsfil. I det sidste trin opretter vi en indstillingsfil og initialiserer en tom database.', - 'Explanatory_Text_1_DB_Intro' => 'Den første ting, du skal gøre, er at oprette en ny, TOM database og en database bruger, der har fuld adgang til databasen. Dette gøres normalt via dit websted Kontrolpanel. Når du har oprettet databasen, skal du indtaste oplysningerne om den pågældende database i tekstelementerne på denne side.', - - 'Explanatory_Text_2_Region_Bias_Intro' => 'Den "Region Bias" er en kode, der er sendt til Google, når en placering søgningen er færdig, og kan hjælpe Google til at få mening ud af tvetydige søgeforespørgsler.', - 'Explanatory_Text_2_API_key_Intro' => '"API-nøgle" er en nøgle, som you need to register with Google in order to be able to use their mapping service.', - 'Explanatory_Text_2_API_key_2_Intro' => 'Du skal angive en gyldig API-nøgle for at oprette nye møder i Rootserveren.', - - 'Explanatory_Text_3_Server_Admin_Intro' => 'Serveradministratoren er hovedbrugeren til serveren. Det er den eneste konto, der kan skabe nye brugere og serviceorganer, og er meget kraftfuld. Du skal oprette et login-id og en ikke-triviel adgangskode til denne konto. Du kan ændre de øvrige aspekter af kontoen på hovedserveren, når databasen er oprettet.', - 'Explanatory_Text_3_Misc_Intro' => 'Disse er forskellige indstillinger, der påvirker hvordan rodserveren opfører sig og vises.', - - 'Explanatory_Text_4_Main_Intro' => 'Hvis du har indtastet database oplysningerne, og hvis du har angivet loginoplysningerne til serveradministratoren, kan du initialisere databasen her. Husk at databasen skal være HELT TOM for BMLT Root Server tabeller for denne server (Det kan have tabeller til andre servere eller tjenester).', - 'Explanatory_Text_4_NAWS_Export' => 'Optionally, you can import the meetings from a NAWS export spreadsheet. Uncheck the box to initialize them to \'unpublished\'. (This is useful if many of the new meetings will need to be edited or deleted, and you don\'t want them showing up in the meantime.)', - 'Explanatory_Text_4_File_Intro' => 'Teksten i boksen nedenfor er PHP kildekoden for hovedindstillingsfilen. Du skal oprette en fil på serveren med denne tekst i den. Filen er på samme niveau som hovedservermappen for rodserveren.', - 'Explanatory_Text_4_File_Extra' => 'Du skal også sikre dig, at filtilladelserne er begrænset (chmod 0644). Dette forhindrer filen i at blive skrevet, og rodserveren kører ikke, medmindre filen har de korrekte tilladelser.', - 'Page_4_PathInfo' => 'Filen skal placeres som %s/auto-config.inc.php, hvor din% s-mappe er. Når filen er oprettet, og du har lagt ovenstående tekst i den, skal du udføre følgende kommando for at sikre, at tilladelserne er korrekte:', - 'Page_4_Final' => 'Når alt dette er færdig, opdatere denne side, og du bør kunne se root serveren login siden.', - 'FormatLangNamesLabel' => 'Enter extra languages in format code1:name1 (example "fa:farsi ru:russian"):', - - ); diff --git a/src/legacy/local_server/server_admin/lang/dk/name.txt b/src/legacy/local_server/server_admin/lang/dk/name.txt deleted file mode 100644 index 4ddab201f..000000000 --- a/src/legacy/local_server/server_admin/lang/dk/name.txt +++ /dev/null @@ -1 +0,0 @@ -Dansk \ No newline at end of file diff --git a/src/legacy/local_server/server_admin/lang/dk/server_admin_strings.inc.php b/src/legacy/local_server/server_admin/lang/dk/server_admin_strings.inc.php deleted file mode 100644 index b2a0a5ca7..000000000 --- a/src/legacy/local_server/server_admin/lang/dk/server_admin_strings.inc.php +++ /dev/null @@ -1,493 +0,0 @@ -. */ - -defined('BMLT_EXEC') or die('Cannot Execute Directly'); // Makes sure that this file is in the correct context. - -$comdef_server_admin_strings = array( - 'server_admin_disclosure' => 'Server Administration', - 'server_admin_naws_spreadsheet_label' => 'Updated World Committee Codes Spreadsheet', - 'update_world_ids_button_text' => 'Update World Committee Codes', - 'update_world_ids_from_spreadsheet_dropdown_text' => 'Update World Committee Codes (Group IDs from NAWS) from NAWS Spreadsheet', - 'server_admin_error_no_world_ids_updated' => 'No World IDs were updated. This could be because your user does not have permission to update the submitted meetings.', - 'server_admin_error_required_spreadsheet_column' => 'Required column does not exist in the spreadsheet: ', - 'server_admin_error_bmlt_id_not_integer' => 'The provided bmlt_id is not an integer: ', - 'server_admin_error_could_not_create_reader' => 'Could not create reader for file: ', - 'server_admin_error_no_files_uploaded' => 'No files were uploaded.', - 'server_admin_error_service_bodies_already_exist' => 'Service bodies with the following World IDs already exist: ', - 'server_admin_error_meetings_already_exist' => 'Meetings with the following World IDs already exist: ', - 'server_admin_ui_num_meetings_updated' => 'Number of meetings updated: ', - 'server_admin_ui_num_meetings_not_updated' => 'Number of meetings that did not need updating: ', - 'server_admin_ui_warning' => 'WARNING', - 'server_admin_ui_errors' => 'Error(s)', - 'server_admin_ui_deleted_meetings_marked' => 'Number of deleted meetings marked so that they won\'t appear in future NAWS exports: ', - 'server_admin_ui_problem_meetings' => 'meetings were found in the spreadsheet that couldn\'t be updated. Problem meeting IDs: ', - 'server_admin_ui_service_bodies_created' => 'Service bodies created: ', - 'server_admin_ui_meetings_created' => 'Meetings created: ', - 'server_admin_ui_users_created' => 'Users created: ', - 'server_admin_ui_refresh_ui_text' => 'Sign out and then sign in again to see the new service bodies, users, and meetings.', - 'import_service_bodies_and_meetings_button_text' => 'Import Service Bodies and Meetings', - 'import_service_bodies_and_meetings_dropdown_text' => 'Import Service Bodies and Meetings from NAWS Export', - 'server_admin_naws_import_spreadsheet_label' => 'NAWS Import Spreadsheet:', - 'server_admin_naws_import_initially_publish' => 'Initialize imported meetings to \'published\': ', - 'server_admin_naws_import_explanation' => 'Uncheck the box to initialize imported meetings to \'unpublished\'. (This is useful if many of the new meetings will need to be edited or deleted, and you don\'t want them showing up in the meantime.)', - 'account_disclosure' => 'Min konto', - 'account_name_label' => 'Min Kontonavn:', - 'account_login_label' => 'Mit Login:', - 'account_type_label' => 'Jeg er en:', - 'account_type_1' => 'Server Administrator', - 'account_type_2' => 'Service Body Administrator', - 'ServerMapsURL' => 'https://maps.googleapis.com/maps/api/geocode/xml?address=##SEARCH_STRING##&sensor=false', - 'account_type_4' => 'hacker? tilsyneladende ikke', - 'account_type_5' => 'Service enhed overvåger', - 'change_password_label' => 'Ændre kodeord Til:', - 'change_password_default_text' => 'Efterlad tomt, hvis du ikke vil ændre dit kodeord', - 'account_email_label' => 'Min Mail Adresse:', - 'email_address_default_text' => 'Indsæt en Mail Aderesse', - 'account_description_label' => 'My Description:', - 'account_description_default_text' => 'Lav en beskrivelse', - 'account_change_button_text' => 'Skift mine kontoindstillinger', - 'account_change_fader_success_text' => 'Kontooplysningerne blev ændret succesfuldt', - 'account_change_fader_failure_text' => 'Kontooplysningerne blev ikke ændret', - 'meeting_editor_disclosure' => 'Møde Editor', - 'meeting_editor_already_editing_confirm' => 'Du redigerer for øjeblikket et andet møde. Ønsker du at miste alle ændringer i det møde?', - 'meeting_change_fader_success_text' => 'Mødet blev succesfuldt ændret', - 'meeting_change_fader_failure_text' => 'Mødet blev ikke ændret', - 'meeting_change_fader_success_delete_text' => 'Mødet blev slettet med succes', - 'meeting_change_fader_fail_delete_text' => 'Mødet blev ikke slettet', - 'meeting_change_fader_success_add_text' => 'Det nye møde blev tilføjet succesfuldt', - 'meeting_change_fader_fail_add_text' => 'Det nye møde blev ikke tilføjet', - 'meeting_text_input_label' => 'Søg efter tekst:', - 'access_service_body_label' => 'Jeg har adgang til:', - 'meeting_text_input_default_text' => 'Indtast nogle søgeord', - 'meeting_text_location_label' => 'Dette er en placering eller postkode', - 'meeting_search_weekdays_label' => 'Søg efter udvalgte hverdage:', - 'meeting_search_weekdays_names' => array('Alle', 'Søndag', 'Mandag', 'Tirsdag', 'Onsdag', 'Torsdag', 'Fredag', 'Lørdag'), - 'meeting_search_service_bodies_label' => 'Søg i valgte service Enhed:', - 'meeting_search_start_time_label' => 'Søg efter møde Starttid:', - 'meeting_search_start_time_all_label' => 'Enhver tid', - 'meeting_search_start_time_morn_label' => 'Morgen', - 'meeting_search_start_time_aft_label' => 'Eftermiddag', - 'meeting_search_start_time_eve_label' => 'Aften', - 'meeting_search_no_results_text' => 'Ingen møder fundet', - 'meeting_editor_tab_specifier_text' => 'Søg efter møder', - 'meeting_editor_tab_editor_text' => 'Rediger møder', // TODO: change to 'Edit Or Create Meetings' - 'meeting_editor_create_new_text' => 'Opret et nyt møde', - 'meeting_editor_location_map_link' => 'Placerings kort', - 'meeting_editor_screen_match_map_button' => 'Indstil kort til adresse', - 'meeting_editor_screen_match_ll_button' => 'Indstil længdegrad og breddegrad til adresse', - 'meeting_editor_screen_default_text_prompt' => 'Indtast noget tekst eller et nummer', - 'meeting_is_published' => 'Møde er offentliggjort', - 'meeting_unpublished_note' => 'Note: Unpublishing a meeting indicates a temporary closure. If this meeting has closed permanently, please delete it.', - 'meeting_editor_screen_meeting_name_label' => 'Møde navn:', - 'meeting_editor_screen_meeting_name_prompt' => 'Indtast et mødenavn', - 'meeting_editor_screen_meeting_weekday_label' => 'Ugedag:', - 'meeting_editor_screen_meeting_start_label' => 'Møde Starttid:', - 'meeting_editor_screen_meeting_time_zone_label' => 'Meeting Time Zone:', - 'meeting_editor_screen_meeting_am_label' => 'AM', - 'meeting_editor_screen_meeting_pm_label' => 'PM', - 'meeting_editor_screen_meeting_noon_label' => 'Middag', - 'meeting_editor_screen_meeting_midnight_label' => 'Midnat', - 'meeting_editor_screen_meeting_duration_label' => 'Varighed:', - 'meeting_editor_screen_meeting_oe_label' => 'Åben-Sluttede', - 'meeting_editor_screen_meeting_cc_label' => 'Verdens Komite Kode:', - 'meeting_editor_screen_meeting_cc_advice' => 'Normally leave this field alone (see documentation).', // TODO: translate - 'meeting_editor_screen_meeting_contact_label' => 'Møde Email Kontakt:', - 'meeting_editor_screen_meeting_contact_prompt' => 'Indtast en e-mail for kun en kontakt til dette møde', - 'meeting_editor_screen_meeting_sb_label' => 'Service enhed:', - 'meeting_editor_screen_meeting_sb_default_value' => 'Ingen Service Body Selected', - 'meeting_editor_screen_meeting_longitude_label' => 'Længdegrad:', - 'meeting_editor_screen_meeting_longitude_prompt' => 'Indtast en længdegrad', - 'meeting_editor_screen_meeting_latitude_label' => 'Højdegrad:', - 'meeting_editor_screen_meeting_latitude_prompt' => 'Indtast en Højdegrad', - 'meeting_editor_screen_meeting_location_label' => 'Længdegrad:', - 'meeting_editor_screen_meeting_location_prompt' => 'Indtast et stednavn (som et bygningsnavn)', - 'meeting_editor_screen_meeting_info_label' => 'Ekstra Info:', - 'meeting_editor_screen_meeting_info_prompt' => 'Indtast eventuelle yderligere placeringsoplysninger', - 'meeting_editor_screen_meeting_street_label' => 'Gade Adresse:', - 'meeting_editor_screen_meeting_street_prompt' => 'Indtast et gadenavn', - 'meeting_editor_screen_meeting_neighborhood_label' => 'Naboskab:', - 'meeting_editor_screen_meeting_neighborhood_prompt' => 'Indtast et naboskab(ikke bydel eller byunderafdeling)', - 'meeting_editor_screen_meeting_borough_label' => 'Bydel / By område:', - 'meeting_editor_screen_meeting_borough_prompt' => 'Indtast en by eller område(ikke naboskab)', - 'meeting_editor_screen_meeting_city_label' => 'By:', - 'meeting_editor_screen_meeting_city_prompt' => 'Indtast et by eller bynavn(ikke amt eller by)', - 'meeting_editor_screen_meeting_county_label' => 'Amt /provinsen afdeling:', - 'meeting_editor_screen_meeting_county_prompt' => 'Indtast et navn på amt eller provinsens afdeling navn', - 'meeting_editor_screen_meeting_state_label' => 'Amt / Provins:', - 'meeting_editor_screen_meeting_state_prompt' => 'Indtast et amt eller provinsnavn', - 'meeting_editor_screen_meeting_zip_label' => 'Postnr:', - 'meeting_editor_screen_meeting_zip_prompt' => 'Indtast et postnummer', - 'meeting_editor_screen_meeting_nation_label' => 'Nation:', - 'meeting_editor_screen_meeting_nation_prompt' => 'Indtast nationens navn', - 'meeting_editor_screen_meeting_comments_label' => 'Comments:', - 'meeting_editor_screen_meeting_train_lines_label' => 'Train Lines:', - 'meeting_editor_screen_meeting_bus_lines_label' => 'Bus Lines:', - 'meeting_editor_screen_meeting_phone_meeting_number_label' => 'Phone Meeting Dial-in Number:', - 'meeting_editor_screen_meeting_phone_meeting_number_prompt' => 'Enter the dial-in number for a phone or virtual meeting', - 'meeting_editor_screen_meeting_virtual_meeting_link_label' => 'Virtual Meeting Link:', - 'meeting_editor_screen_meeting_virtual_meeting_link_prompt' => 'Enter the link for a virtual meeting', - 'meeting_editor_screen_meeting_virtual_meeting_additional_info_label' => 'Virtual Meeting Additional Information:', - 'meeting_editor_screen_meeting_virtual_meeting_additional_info_prompt' => 'Enter any additional information for joining the virtual meeting, including directly from the app. For example, if the meeting uses Zoom, "Zoom ID: 456 033 8613, Passcode: 1953" would be appropriate.', - 'meeting_editor_screen_meeting_venue_type' => 'Venue Type:', - 'meeting_editor_screen_meeting_venue_type_inperson' => 'In-Person', - 'meeting_editor_screen_meeting_venue_type_virtual' => 'Virtual', - 'meeting_editor_screen_meeting_venue_type_virtualTC' => 'Virtual (temporarily replacing an in-person)', - 'meeting_editor_screen_meeting_venue_type_hybrid' => 'Hybrid (both in-person and virtual)', - 'meeting_editor_screen_meeting_venue_type_validation' => 'You must select a venue type.', - 'meeting_editor_screen_meeting_virtual_info_missing' => 'Virtual or hybrid meetings must have a Virtual Meeting Link, a Phone Meeting Dial-in Number, or Virtual Meeting Additional Information', - 'meeting_editor_screen_meeting_location_warning' => 'Meeting should have a location (at least a city/town and state/province, or a zip/postal code).', - 'meeting_editor_screen_meeting_address_warning' => 'In-person or hybrid meetings should have a street address.', - 'meeting_editor_screen_meeting_url_validation' => 'Virtual Meeting Link is not a valid URL.', - 'meeting_editor_screen_meeting_url_or_phone_warning' => 'Virtual or hybrid meetings should have either a Virtual Meeting Link or a Phone Meeting Dial-in Number', - 'meeting_editor_screen_meeting_additional_warning' => 'Please also fill in Virtual Meeting Additional Information if there is a Virtual Meeting Link.', - 'meeting_editor_screen_in_person_virtual_info_warning' => 'In-person meetings shouldn\'t have any virtual meeting information.', - 'meeting_editor_screen_meeting_virtual_location_info_warning' => 'Virtual meetings shouldn\'t have a location name or address.', - 'meeting_editor_screen_meeting_validation_warning' => 'There are warnings. Are you sure you want to save anyway? If not, press \'cancel\' and go to the Location tab to see the warnings in place and address them.', - 'meeting_editor_screen_meeting_validation_failed' => 'Unable to save due to input errors. Please go to the Location tab to address them, and then retry saving. Errors: ', - 'meeting_editor_screen_meeting_validation_warnings' => 'Input warnings shown on the Location tab: ', - 'meeting_editor_screen_meeting_contact_name_1_label' => 'Contact 1 Name:', - 'meeting_editor_screen_meeting_contact_email_1_label' => 'Contact 1 Email:', - 'meeting_editor_screen_meeting_contact_phone_1_label' => 'Contact 1 Phone:', - 'meeting_editor_screen_meeting_contact_name_2_label' => 'Contact 2 Name:', - 'meeting_editor_screen_meeting_contact_email_2_label' => 'Contact 2 Email:', - 'meeting_editor_screen_meeting_contact_phone_2_label' => 'Contact 2 Phone:', - 'meeting_editor_screen_meeting_publish_search_prompt' => 'Se efter:', - 'meeting_editor_screen_meeting_publish_search_pub' => 'Kun offentliggjorte møder', - 'meeting_editor_screen_meeting_publish_search_unpub' => 'Kun ikke offentliggjorte møder', - 'meeting_editor_screen_meeting_visibility_advice' => 'Dette vises aldrig i normale mødesøgninger.', - 'meeting_editor_screen_meeting_publish_search_all' => 'Alle møder', - 'meeting_editor_screen_meeting_create_button' => 'Opret et nyt møde', - 'meeting_editor_screen_delete_button' => 'Slet dette møde', - 'meeting_editor_screen_delete_button_confirm' => 'Er du sikker på, at du vil slette dette møde?', - 'meeting_editor_screen_cancel_button' => 'Annulerer', - 'logout' => 'Log ud', - 'meeting_editor_screen_cancel_confirm' => 'Er du sikker på at du vil annullere redigering af dette møde og miste alle ændringer?', - 'meeting_lookup_failed' => 'Adressesøgningen mislykkedes.', - 'meeting_lookup_failed_not_enough_address_info' => 'Der er ikke nok gyldige adresseoplysninger til at foretage en søgning.', - 'meeting_create_button_name' => 'Gem dette som nyt møde', - 'meeting_saved_as_a_copy' => 'Gem dette møde som en kopi(opretter et nyt møde)', - 'meeting_save_buttonName' => 'Gem ændringerne til dette møde ', - 'meeting_editor_tab_bar_basic_tab_text' => 'Grundlæggende', - 'meeting_editor_tab_bar_location_tab_text' => 'Beliggenhed', - 'meeting_editor_tab_bar_format_tab_text' => 'Format', - 'meeting_editor_tab_bar_other_tab_text' => 'Andet', - 'meeting_editor_tab_bar_history_tab_text' => 'Historie', - 'meeting_editor_result_count_format' => '%d Møder fundet', - 'meeting_id_label' => 'Møde ID:', - 'meeting_editor_default_zoom' => '13', - 'meeting_editor_default_weekday' => '2', - 'meeting_editor_default_start_time' => '20:30:00', - 'meeting_editor_default_duration' => '01:30:00', - 'login_banner' => 'Basic Meeting List Toolbox', - 'login_underbanner' => 'Root Server Administration Console', - 'login' => 'Login ID', - 'password' => 'Kodeord', - 'button' => 'Log Ind', - 'cookie' => 'Du skal aktivere cookies for at administrere denne server.', - 'noscript' => 'Du kan ikke administrere denne side uden JavaScript.', - 'title' => 'Log venligst ind for at administrere serveren.', - 'edit_Meeting_object_not_found' => 'FEJL: Mødet blev ikke fundet.', - 'edit_Meeting_object_not_changed' => 'FEJL: Mødet blev ikke ændret.', - 'edit_Meeting_auth_failure' => 'Du har ikke tilladelse til at redigere dette møde.', - 'not_auth_1' => 'IKKE AUTORISERET', - 'not_auth_2' => 'Du har ikke tilladelse til at administrere denne server.', - 'not_auth_3' => 'Der opstod et problem med brugernavnet eller adgangskoden, du indtastede.', - 'email_format_bad' => 'Den email-adresse, du indtastede, blev ikke formateret korrekt.', - 'history_header_format' => '
%sby %s
', - 'history_no_history_available_text' => '

Ingen historie tilgængelig til dette møde

', - 'service_body_editor_disclosure' => 'Service enhed Administration', - 'service_body_change_fader_success_text' => 'Service enheden blev succesfuldt ændret', - 'service_body_change_fader_fail_text' => 'Services enhedens ændring mislykkedes', - 'service_body_editor_screen_sb_id_label' => 'ID:', - 'service_body_editor_screen_sb_name_label' => 'Navn:', - 'service_body_name_default_prompt_text' => 'Indtast navnet på denne service enhed', - 'service_body_parent_popup_label' => 'Service Enhedens forældre:', - 'service_body_parent_popup_no_parent_option' => 'Ingen forælder (øverste niveau)', - 'service_body_editor_screen_sb_admin_user_label' => 'Primær Administrator:', - 'service_body_editor_screen_sb_admin_description_label' => 'Beskrivelse:', - 'service_body_description_default_prompt_text' => 'Indtast en beskrivelse af denne service enhed', - 'service_body_editor_screen_sb_admin_email_label' => 'Kontakt Email:', - 'service_body_email_default_prompt_text' => 'Indtast en kontakt-e-mail-adresse for denne service enhed', - 'service_body_editor_screen_sb_admin_uri_label' => 'Web Side URL:', - 'service_body_uri_default_prompt_text' => 'Indsæt en Web Side URL for denne Service Enhed', - 'service_body_editor_screen_sb_admin_full_editor_label' => 'Fuld møde liste redaktører:', - 'service_body_editor_screen_sb_admin_full_editor_desc' => 'Disse brugere kan redigere eventuelle møder i denne service enhed.', - 'service_body_editor_screen_sb_admin_editor_label' => 'Grundlæggende møde liste redaktører:', - 'service_body_editor_screen_sb_admin_editor_desc' => 'Disse brugere kan redigere eventuelle møder i denne service enhed, men kun hvis de er upubliceret.', - 'service_body_editor_screen_sb_admin_observer_label' => 'Observatører:', - 'service_body_editor_screen_sb_admin_observer_desc' => 'Disse brugere kan se skjult info (som e-mail-adresser), men kan ikke redigere noget.', - 'service_body_dirty_confirm_text' => 'Du har foretaget ændringer til denne service enhed. Ønsker du at miste dine ændringer?', - 'service_body_save_button' => 'Gem disse ændringer for Service Enheden', - 'service_body_create_button' => 'Opret denne service Enhed', - 'service_body_delete_button' => 'Slet denne service Enhed', - 'service_body_delete_perm_checkbox' => 'Slet Denne Service Enhed Permanent', - 'service_body_delete_button_confirm' => 'Er du sikker på, at du vil slette denne service Enhed? Make sure that all meetings are either removed or transferred to another service body before performing this function.', - 'service_body_delete_button_confirm_perm' => 'Denne service enhed vil blive slettet permanent!', - 'service_body_change_fader_create_success_text' => 'Denne Service Enhed Blev Oprettet Succesfuld ', - 'service_body_change_fader_create_fail_text' => 'Oprettelse Service Enheden Mislykkedes', - 'service_body_change_fader_delete_success_text' => 'Service Enheden Blev Slettet', - 'service_body_change_fader_delete_fail_text' => 'Slettelse Af Service Enheden Mislykkedes', - 'service_body_change_fader_fail_no_data_text' => 'Ændring Af Service Enheden Mislykkedes, Fordi Der Ikke Var Nogen Data Leveret', - 'service_body_change_fader_fail_cant_find_sb_text' => 'Ændring Af Service Enheden Mislykkedes, Fordi Service Enheden Ikke Blev Fundet', - 'service_body_change_fader_fail_cant_update_text' => 'Ændring Af Service Enheden Mislykkedes, Fordi Service Enheden Ikke Blev Opdateret', - 'service_body_change_fader_fail_bad_hierarchy' => 'Ændring Af Service Enheden Mislykkedes, Fordi Den Udvalgte Ejerens Service Enhed Er Under Denne Service Enhed Og Kan Ikke Bruges', - 'service_body_cancel_button' => 'Gendan til original', - 'service_body_editor_type_label' => 'Service Enhed Type:', - 'service_body_editor_type_c_comdef_service_body__GRP__' => 'Gruppe', - 'service_body_editor_type_c_comdef_service_body__COP__' => 'Samarbejde', - 'service_body_editor_type_c_comdef_service_body__ASC__' => 'Område Service Komite ', - 'service_body_editor_type_c_comdef_service_body__RSC__' => 'Regionale service konference', - 'service_body_editor_type_c_comdef_service_body__WSC__' => 'Verdens Service Konference', - 'service_body_editor_type_c_comdef_service_body__MAS__' => 'Metroområde', - 'service_body_editor_type_c_comdef_service_body__ZFM__' => 'Zone', - 'service_body_editor_type_c_comdef_service_body__GSU__' => 'Gruppe Service Enhed', - 'service_body_editor_type_c_comdef_service_body__LSU__' => 'Lokal Service Enhed', - 'service_body_editor_screen_helpline_label' => 'Helpline:', - 'service_body_editor_screen_helpline_prompt' => 'Indtast Telefonnummeret Til Helpline', - 'service_body_editor_uri_naws_format_text' => 'Få Møder Til Denne service Enhed Som En NAWS-Kompatibel Fil', - 'edit_Meeting_meeting_id' => 'Møde ID:', - 'service_body_editor_create_new_sb_option' => 'Opret En Ny Service Enhed', - 'service_body_editor_screen_world_cc_label' => 'Verdens Komite Kode:', - 'service_body_editor_screen_world_cc_prompt' => 'Indtast En Verdens Komite Kode', - 'user_editor_disclosure' => 'Bruger Administration', - 'user_editor_create_new_user_option' => 'Opret En Ny Bruger', - 'user_editor_screen_sb_id_label' => 'ID:', - 'user_editor_account_login_label' => 'Bruger Login:', - 'user_editor_login_default_text' => 'Indtast Et Bruger Login', - 'user_editor_account_type_label' => 'Bruger Er En:', - 'user_editor_user_owner_label' => 'Ejet Af: ', - 'user_editor_account_type_1' => 'Server Administrator', - 'user_editor_account_type_2' => 'Service Enheds Administrator', - 'user_editor_account_type_3' => 'Service Enheds Redaktør', - 'user_editor_account_type_5' => 'Service Enheds Observant', - 'user_editor_account_type_4' => 'Deaktiveret bruger', - 'user_editor_account_name_label' => 'Bruger Navn:', - 'user_editor_name_default_text' => 'Indsæt Et Bruger Navn', - 'user_editor_account_description_label' => 'Beskrivelse:', - 'user_editor_description_default_text' => 'Indsæt En Bruger Beskrivelse', - 'user_editor_account_email_label' => 'Email:', - 'user_editor_email_default_text' => 'Indsæt En Bruger Email', - 'user_change_fader_success_text' => 'Brugeren blev ændret succesfuldt', - 'user_change_fader_fail_text' => 'Brugerændringen mislykkedes', - 'user_change_fader_create_success_text' => 'Brugeren blev oprettet', - 'user_change_fader_create_fail_text' => 'Oprettelse Af Bruger Mislykkedes', - 'user_change_fader_create_fail_already_exists' => 'En login til den bruger, du forsøger at oprette, eksisterer allerede.', - 'user_change_fader_delete_success_text' => 'Brugeren blev slettet', - 'user_change_fader_delete_fail_text' => 'Sletningen Brugen Mislykkedes', - 'user_save_button' => 'Gem Ændringer Til Denne Bruger', - 'user_create_button' => 'Opret Denne Nye Bruger', - 'user_cancel_button' => 'Gendan til original', - 'user_delete_button' => 'Slet Denne Bruger', - 'user_delete_perm_checkbox' => 'Slet Denne Bruger Permanent', - 'user_password_label' => 'Skift Adgangskode Til:', - 'user_new_password_label' => 'Angiv Adgangskode Til:', - 'user_password_default_text' => 'Forlad dette alene, medmindre du vil ændre adgangskoden', - 'user_new_password_default_text' => 'Du skal indtaste et kodeord for en ny bruger', - 'user_dirty_confirm_text' => 'Du har foretaget ændringer til denne bruger. Ønsker du at miste dine ændringer?', - 'user_delete_button_confirm' => 'Er Du Sikker På, At Du Vil Slette Denne Bruger?', - 'user_delete_button_confirm_perm' => 'Denne Bruger Bliver Slettet Permanent!', - 'user_create_password_alert_text' => 'Nye Brugere Skal Have Adgangskode. Du Har Ikke Angivet En Adgangskode Til Denne Bruger.', - 'user_change_fader_fail_no_data_text' => 'Brugerændringen Mislykkedes, Fordi Der Ikke Var Nogen Data Leveret', - 'user_change_fader_fail_cant_find_sb_text' => 'Brugerændringen Mislykkedes, Fordi Brugeren Ikke Blev Fundet', - 'user_change_fader_fail_cant_update_text' => 'Brugerændringen Mislykkedes, Fordi Brugeren Ikke Blev Opdateret', - 'format_editor_disclosure' => 'Format Administration', - 'format_change_fader_change_success_text' => 'Formatet Blev Ændret Succesfuldt', - 'format_change_fader_change_fail_text' => 'Format Ændringen Mislykkedes', - 'format_change_fader_create_success_text' => 'Formatet Blev Oprettet Succesfuldt', - 'format_change_fader_create_fail_text' => 'Oprettelse Af Formatet Mislykkes', - 'format_change_fader_delete_success_text' => 'Formatet Blev Slettet', - 'format_change_fader_delete_fail_text' => 'Sletning Af Format Mislykkedes', - 'format_change_fader_fail_no_data_text' => 'Format Ændring Mislykkedes, Fordi Der Ikke Var Data Leveret', - 'format_change_fader_fail_cant_find_sb_text' => 'Format Ændring Mislykkes, Fordi Formatet Ikke Blev Fundet', - 'format_change_fader_fail_cant_update_text' => 'Format Ændring Mislykkes, Fordi Formatet Ikke Blev Opdateret', - 'format_editor_name_default_text' => 'Indsæt En Meget Kort Beskrivelse', - 'format_editor_description_default_text' => 'Indsæt En Mere Detaljeret Beskrivelse', - 'format_editor_create_format_button_text' => 'Opret Nyt Format', - 'format_editor_cancel_create_format_button_text' => 'Annullere', - 'format_editor_create_this_format_button_text' => 'Opret Dette Format', - 'format_editor_change_format_button_text' => 'Skift Dette Format', - 'format_editor_delete_format_button_text' => 'Slet Dette Format', - 'format_editor_reset_format_button_text' => 'Gendan Til Original', - 'need_refresh_message_fader_text' => 'Du bør opdatere denne side, før du bruger denne sektion', - 'need_refresh_message_alert_text' => 'Hvis du har foretaget ændringer i Service Body Administration, User Administration eller Format Administration, kan oplysningerne, der vises i dette afsnit, ikke længere være korrekte, så siden skal opdateres. Den nemmeste måde at gøre dette på er at logge ud og derefter logge på igen.', - 'format_editor_delete_button_confirm' => 'Er du sikker på, at du vil slette dette format?', - 'format_editor_delete_button_confirm_perm' => 'Dette format slettes permanent!', - 'format_editor_missing_key' => 'This format should have an entry for every language (at least a key).', // TODO: translate - 'format_editor_reserved_key' => 'This key is reserved for a venue type format - please use something different.', // TODO: translate - 'min_password_length_string' => 'Adgangskoden er for kort! Det skal være mindst% d tegn langt!', - 'AJAX_Auth_Failure' => 'Autorisation mislykkedes for denne operation. Der kan være et problem med serverkonfigurationen.', - 'Maps_API_Key_Warning' => 'ADVARSEL: Der er et problem med API-nøglen til Google Maps.', - 'Maps_API_Key_Not_Set' => 'ADVARSEL: Google Maps API-nøglen er ikke angivet.', - 'Observer_Link_Text' => 'Meeting Browser', - 'Data_Transfer_Link_Text' => 'Importer mødedata (ADVARSEL: Erstatter nuværende data!)', - 'MapsURL' => 'https://maps.google.com/maps?q=##LAT##,##LONG##+(##NAME##)&ll=##LAT##,##LONG##', - 'hidden_value' => 'Kan ikke vise data - Uautoriseret', - 'Value_Prompts' => array( - 'id_bigint' => 'Møde ID', - 'worldid_mixed' => 'Verdens Services ID', - 'service_body' => 'Service Enhed', - 'service_bodies' => 'Service Enheder', - 'weekdays' => 'Ugedage', - 'weekday' => 'Møde samles hver', - 'start_time' => 'Møde begynder kl', - 'duration_time' => 'Møde vare', - 'location' => 'Beliggenhed', - 'duration_time_hour' => 'Time', - 'duration_time_hours' => 'Timer', - 'duration_time_minute' => 'Minut', - 'duration_time_minutes' => 'Minutter', - 'lang_enum' => 'Sprog', - 'formats' => 'Struktur', - 'distance' => 'Afstand fra Centrum', - 'generic' => 'NA Møde', - 'close_title' => 'Luk Dette Mødestruktur Vindue', - 'close_text' => 'Luk Vindue', - 'map_alt' => 'Kort til møde', - 'map' => 'Følg denne link til et kort', - 'title_checkbox_unpub_meeting' => 'Dette møde er ikke udgivet. Det kan ikke ses ved regelmæssige søgninger.', - 'title_checkbox_copy_meeting' => 'Dette møde er et duplikat af et andet møde. Det er ikke udgivet. Det kan ikke ses ved regelmæssige søgninger.' - ), - 'world_format_codes_prompt' => 'NAWS Format:', - 'world_format_codes' => array( - '' => 'None', - 'OPEN' => 'Åben', - 'CLOSED' => 'Lukket', - 'WCHR' => 'Kørestolsvenligt', - 'BEG' => 'Begynder / Nykommer', - 'BT' => 'Basis Tekst', - 'CAN' => 'Lysmøde', - 'CPT' => '12 koncepter', - 'CW' => 'Børn Er Velkommen', - 'DISC' => 'Diskussion / Deltagelse', - 'GL' => 'Homoseksuel / lesbisk', - 'IP' => 'IP Møde', - 'IW' => 'Det Virker Møde', - 'JFT' => 'Bare For I Dag Møde', - 'LC' => 'Living Clean', - 'LIT' => 'Litteratur Møde', - 'M' => 'Mandemøde', - 'MED' => 'Meditation', - 'NS' => 'Ikke Ryger', - 'QA' => 'Spørgsmål & Svar', - 'RA' => 'Restriktiv Møde', - 'S-D' => 'Speaker/Discussion', // TODO translate - 'SMOK' => 'Ryger', - 'SPK' => 'Speaker', - 'STEP' => 'Trin', - 'SWG' => 'Step Working Guide Møde', - 'TOP' => 'Emne', - 'TRAD' => 'Tradition', - 'VAR' => 'Skiftende Struktur', - 'W' => 'Kvinde', - 'Y' => 'Ungdoms Møde', - 'LANG' => 'Alternativt sprog', - 'GP' => 'Guiding Principles', // TODO translate - 'NC' => 'No Children', // TODO translate - 'CH' => 'Closed Holidays', // TODO translate - 'VM' => 'Virtual', // TODO translate - 'HYBR' => 'Virtual and In-Person', // TODO translate - 'TC' => 'Temporarily Closed Facility', // TODO translate - 'SPAD' => 'Spiritual Principle a Day', // TODO translate - ), - 'format_type_prompt' => 'Format Type:', // TODO: Translate - 'format_type_codes' => array( - '' => 'None', // TODO: Translate - 'FC1' => 'Meeting Format (Speaker, Book Study, etc.)', // TODO: Translate - 'FC2' => 'Location Code (Wheelchair Accessible, Limited Parking, etc.)', // TODO: Translate - 'FC3' => 'Common Needs and Restrictions (Mens Meeting, LGTBQ, No Children, etc.)', // TODO: Translate - 'O' => 'Attendance by non-addicts (Open, Closed)', // TODO: Translate - 'LANG' => 'Language', // TODO: TRANSLATE - 'ALERT' => 'Format should be especially prominent (Clean requirement, etc.)',// TODO: Translate - ), - 'cookie_monster' => 'Dette websted bruger en cookie til at gemme dit foretrukne sprog.', - 'main_prompts' => array( - 'id_bigint' => 'ID', - 'worldid_mixed' => 'Verdens ID', - 'shared_group_id_bigint' => 'Ubrugt', - 'service_body_bigint' => 'Service Enhed ID', - 'weekday_tinyint' => 'Ugedag', - 'venue_type' => 'Venue Type', - 'start_time' => 'Starttidspunkt', - 'duration_time' => 'Retning', - 'time_zone' => 'Time Zone', - 'formats' => 'Struktur', - 'lang_enum' => 'Sprog', - 'longitude' => 'Længdegrad', - 'latitude' => 'Højdergrad', - 'published' => 'Udgivet', - 'email_contact' => 'Email Kontakt', - ), - 'check_all' => 'Check All', - 'uncheck_all' => 'Uncheck All', - 'automatically_calculated_on_save' => 'Automatically calculated on save.' -); - -$email_contact_strings = array( - 'meeting_contact_form_subject_format' => "[MØDE LISTE KONTAKT] %s", - 'meeting_contact_message_format' => "%s\n--\nDenne meddelelse vedrører mødet navngivet \"%s\", der mødes %s, on %s.\nBrowser Link: %s\nRedigere Link: %s\nDen blev sendt direkte fra mødelisten webserver, og afsenderen er ikke bekendt med din e-mail-adresse.\nVær opmærksom på, at svaret vil afsløre din e-mail-adresse.\nHvis du bruger \"Svar alle\", og der er flere e-mailmodtagere, kan du udsætte andres e-mailadresser.\nVær venlig at respektere folks privatliv og anonymitet; herunder den oprindelige afsender af denne meddelelse." -); - -$change_type_strings = array( - '__THE_MEETING_WAS_CHANGED__' => 'Mødet blev ændret.', - '__THE_MEETING_WAS_CREATED__' => 'Mødet blev oprettet.', - '__THE_MEETING_WAS_DELETED__' => 'Mødet blev slettet.', - '__THE_MEETING_WAS_ROLLED_BACK__' => 'Mødet blev rullet tilbage til en tidligere version.', - - '__THE_FORMAT_WAS_CHANGED__' => 'Strukturen Blev Ændret.', - '__THE_FORMAT_WAS_CREATED__' => 'Strukturen Blev Oprettet.', - '__THE_FORMAT_WAS_DELETED__' => 'Strukturen Blev Slettet.', - '__THE_FORMAT_WAS_ROLLED_BACK__' => 'Strukturen blev rullet tilbage til en tidligere version.', - - '__THE_SERVICE_BODY_WAS_CHANGED__' => 'Service enheden blev ændret.', - '__THE_SERVICE_BODY_WAS_CREATED__' => 'Service enheden blev Oprettet.', - '__THE_SERVICE_BODY_WAS_DELETED__' => 'Service enheden blev Slettet.', - '__THE_SERVICE_BODY_WAS_ROLLED_BACK__' => 'Service Enheden blev rullet tilbage til en tidligere version.', - - '__THE_USER_WAS_CHANGED__' => 'Brugeren Blev Ændret.', - '__THE_USER_WAS_CREATED__' => 'Brugeren Blev Oprettet.', - '__THE_USER_WAS_DELETED__' => 'Brugeren Blev Slettet.', - '__THE_USER_WAS_ROLLED_BACK__' => 'Brugeren Blev Ruller Tilbage Til En Tidligere Version.', - - '__BY__' => 'fra', - '__FOR__' => 'til' -); - -$detailed_change_strings = array( - 'was_changed_from' => 'blev ændret fra', - 'to' => 'Til', - 'was_changed' => 'blev ændret', - 'was_added_as' => 'blev tilføjet som', - 'was_deleted' => 'Blev Slettet', - 'was_published' => 'Mødet Blev Udhivet', - 'was_unpublished' => 'Mødet Blev Ikke Udgivet', - 'formats_prompt' => 'Møde Strukturen', - 'duration_time' => 'Møde varigheden', - 'start_time' => 'Mødetidspunktet', - 'longitude' => 'Mødets Længdegrad', - 'latitude' => 'Mødets Højdegrad', - 'sb_prompt' => 'Mødet ændrede sin service enhed fra', - 'id_bigint' => 'Møde ID', - 'lang_enum' => 'Møde sproget', - 'worldid_mixed' => 'Den delte gruppe ID', // TODO: translate The World Committee Code - 'weekday_tinyint' => 'Den dag i ugen, hvor mødet holdes', - 'non_existent_service_body' => 'Service enheden findes ikke længere', -); - -defined('_END_CHANGE_REPORT') or define('_END_CHANGE_REPORT', '.'); diff --git a/src/legacy/local_server/server_admin/lang/en/data_transfer_strings.php b/src/legacy/local_server/server_admin/lang/en/data_transfer_strings.php deleted file mode 100755 index 624c60e08..000000000 --- a/src/legacy/local_server/server_admin/lang/en/data_transfer_strings.php +++ /dev/null @@ -1,45 +0,0 @@ -.*/ - defined('BMLT_EXEC') or die('Cannot Execute Directly'); // Makes sure that this file is in the correct context. - - $comdef_data_transfer_strings = array ( 'key_strings' => array ( 'id_bigint' => 1, - 'worldid_mixed' => 1, - 'shared_group_id_bigint' => 1, - 'service_body_bigint' => 1, - 'weekday_tinyint' => 1, - 'start_time' => 1, - 'duration_time' => 1, - 'formats' => 1, - 'lang_enum' => 1, - 'longitude' => 1, - 'latitude' => 1, - 'published' => 1, - 'email_contact' => 1 - ), - - 'days' => array ( 'Sunday', - 'Monday', - 'Tuesday', - 'Wednesday', - 'Thursday', - 'Friday', - 'Saturday' - ), - ); diff --git a/src/legacy/local_server/server_admin/lang/en/install_wizard_strings.php b/src/legacy/local_server/server_admin/lang/en/install_wizard_strings.php deleted file mode 100755 index 787540565..000000000 --- a/src/legacy/local_server/server_admin/lang/en/install_wizard_strings.php +++ /dev/null @@ -1,164 +0,0 @@ -.*/ - defined('BMLT_EXEC') or die('Cannot Execute Directly'); // Makes sure that this file is in the correct context. - - global $comdef_install_wizard_strings; - - $comdef_install_wizard_strings = array ( - 'Database_Version_Error' => 'ERROR: You must have PHP Version 5.6 or greater installed on this server!', - 'Database_PDO_Error' => 'ERROR: You do not have PHP PDO installed!', - 'Database_Type_Error' => 'ERROR: Even though you have PDO, you have no database drivers installed!', - 'Database_Type_MySQL_Error' => 'ERROR: Even though you have PDO and you have database drivers installed, none of the are MySQL (the only supported driver)!', - 'Database_TestButton_Text' => 'TEST', - 'Database_TestButton_Success' => 'The database connection was successful.', - 'Database_TestButton_Fail' => 'The database connection failed: ', - 'Database_TestButton_Fail2' => 'The database connection failed because there is already an initialized database.', - 'Database_Whitespace_Note' => 'Warning: %s has whitespace at the beginning or end.', - - 'AJAX_Handler_DB_Connect_Error' => 'The database connection failed! Please make sure that the database exists, IS COMPLETELY EMPTY, the user is created, and that user has full permissions on the empty database.', - 'AJAX_Handler_DB_Established_Error' => 'The database already exists, and has been set up! You cannot use this setup to overwrite an existing database!', - 'AJAX_Handler_DB_Incomplete_Error' => 'There is not enough information to initialize the database!', - - 'NoDatabase_Note_AlreadySet' => 'The database has already been initialized with the provided table prefix. Please choose a new one.', - 'NoDatabase_Note_GenericError' => 'There is an error connecting to the database. Please check your database settings.', - 'NoDatabase_Note_ClickHere' => 'Click here to go back to the database set up page.', - 'NoDatabase_Note_PasswordIssue' => 'You must choose a username and password for the Server Administrator user.', - 'NoDatabase_Note_ServerSettings_ClickHere' => 'Click here to go back to the server settings page.', - 'NoServerAdmin_Note_AlreadySet' => 'There is already an existing database, so you cannot set up a Server Administrator account (One already exists).', - 'NeedLongerPasswordNote' => 'This password is too short. It must be at least %d characters long.', - - 'Prev_Button' => 'PREVIOUS', - 'Next_Button' => 'NEXT', - - 'Page_1_Tab' => 'STEP 1: Database', - 'Page_1_Heading' => 'Database Connection Settings', - 'Page_1_Text' => 'Before you can apply the settings on this page, you must set up a new COMPLETELY EMPTY database, and create a database user that has full user rights on that database.', - - 'Database_Name' => 'Database Name:', - 'Database_Name_Default_Text' => 'Enter A Database Name', - 'Database_Type' => 'Database Type:', - 'Database_Host' => 'Database Host:', - 'Database_Host_Default_Text' => 'Enter A Database Host', - 'Database_Host_Additional_Text' => 'This is usually "localhost."', - 'Table_Prefix' => 'Table Prefix:', - 'Table_Prefix_Default_Text' => 'Enter A Table Prefix', - 'Table_Prefix_Additional_Text' => 'Only for multiple root servers sharing a database.', - 'Database_User' => 'Database User:', - 'Database_User_Default_Text' => 'Enter A Database User Name', - 'Database_PW' => 'Database Password:', - 'Database_PW_Default_Text' => 'Enter A Database Password', - 'Database_PW_Additional_Text' => 'Make this an ugly, difficult password. It has a great deal of power, and you will never need to remember it.', - - 'Maps_API_Key_Warning' => 'There is a problem with the Google Maps API Key.', - 'Maps_API_Key_Not_Set' => 'The Google Maps API key is not set.', - 'Maps_API_Key_Valid' => 'Google Maps API Key is valid.', - 'Maps_API_Key_ClickHere' => 'Click here to go back to the Google Maps API Key set up page.', - - 'Page_2_Tab' => 'STEP 2: Google Maps API Settings', - 'Page_2_Heading' => 'Google Maps API Settings', - 'Page_2_API_Key_Prompt' => 'Enter the Google API Key for Geocoding:', - 'Page_2_API_Key_Set_Button' => 'TEST KEY', - 'Page_2_API_Key_Not_Set_Prompt' => 'SET API KEY FIRST', - 'Page_2_Text' => 'When saving a meeting, the BMLT Root Server uses the Google Maps API to determine the latitude and longitude for the meeting address. These settings are required to allow the BMLT Root Server to communicate with the Google Maps API.', - - 'Page_3_Tab' => 'STEP 3: Server Settings', - 'Page_3_Heading' => 'Set Various Global Server Settings', - 'Page_3_Text' => 'These are a few settings that affect the administration and general configuration of this server. Most server settings are done in the server itself.', - 'Admin_Login' => 'Server Administrator Login:', - 'Admin_Login_Default_Text' => 'Enter A Server Administrator Login', - 'Admin_Login_Additional_Text' => 'This is the login string for the Server Administrator.', - 'Admin_Password' => 'Server Administrator Password:', - 'Admin_Password_Default_Text' => 'Enter A Server Administrator Password', - 'Admin_Password_Additional_Text' => 'Make sure that this is a non-trivial password! It has a great deal of power! (Also, don\'t forget it).', - 'ServerAdminName' => 'Server Administrator', - 'ServerAdminDesc' => 'Main Server Administrator', - 'ServerLangLabel' => 'Default Server Language:', - 'DistanceUnitsLabel' => 'Distance Units:', - 'DistanceUnitsMiles' => 'Miles', - 'DistanceUnitsKM' => 'Kilometres', - 'SearchDepthLabel' => 'Density of Meetings For Automatic Search:', - 'SearchDepthText' => 'This is an approximation of how many meetings need to be found in the automatic radius selection. More meetings means a bigger radius.', - 'HistoryDepthLabel' => 'How Many Meeting Changes To Save:', - 'HistoryDepthText' => ' The longer the history, the larger the database will become.', - 'TitleTextLabel' => 'The Title Of The Administration Screen:', - 'TitleTextDefaultText' => 'Enter A Short Title For the Editing Login Page', - 'BannerTextLabel' => 'Prompt For Administration Login:', - 'BannerTextDefaultText' => 'Enter A Short Prompt For The Login Page', - 'RegionBiasLabel' => 'Region Bias:', - 'PasswordLengthLabel' => 'Minimum Password Length:', - 'PasswordLengthExtraText' => 'This will also affect the Server Administrator password, above.', - 'DefaultClosedStatus' => 'Meetings Are Considerd "CLOSED" by Default:', - 'DefaultClosedStatusExtraText' => 'This primarily affects the export to NAWS.', - 'DurationLabel' => 'Default Meeting Duration:', - 'DurationHourLabel' => 'Hours', - 'DurationMinutesLabel' => 'Minutes', - 'LanguageSelectorEnableLabel' => 'Display Language Selector On Login:', - 'LanguageSelectorEnableExtraText' => 'If you select this, a popup menu will appear in the login screen, so administrators can select their language.', - 'SemanticAdminLabel' => 'Enable Semantic Administration:', - 'SemanticAdminExtraText' => 'If not checked, then all administration must be done via the Root Server login (No apps).', - 'EmailContactEnableLabel' => 'Allow Email Contacts From Meetings:', - 'EmailContactEnableExtraText' => 'If you select this, site visitors will be able to send emails from meeting records.', - 'EmailContactAdminEnableLabel' => 'Include Service Body Administrator On These Emails:', - 'EmailContactAdminEnableExtraText' => 'Sends copies of these emails to the Service Body Administrator (if they are not the primary recipient).', - 'EmailContactAllAdminEnableLabel' => 'Include All Service Body Administrators On These Emails:', - 'EmailContactAllAdminEnableExtraText' => 'Sends copies of these emails to all of the relevant Service Body Administrators.', - - 'Page_4_Initialize_Root_Server_Heading' => 'Initialize the Root Server', - 'Page_4_Initialize_Root_Server_Text' => 'The button below will initialize the Root Server with an empty database and a Server Administrator user.', - 'Page_4_Initialize_Root_Server_Button' => 'Initialize Root Server', - - 'Page_4_Tab' => 'STEP 4: Save The Settings', - 'Page_4_Heading' => 'Create the Settings File', - 'Page_4_Text' => 'The root server was unable to create the settings file for you. Instead, we ask you to create it yourself, via FTP or a control panel file manager, name it "auto-config.inc.php", and paste the following text into the file:', - - 'NAWS_Export_Spreadsheet_Optional' => 'NAWS Export Spreadsheet (Optional): ', - 'NAWS_Export_Spreadsheet_Initially_Publish' => 'Initialize imported meetings to \'published\': ', - 'DefaultPasswordLength' => 10, - 'DefaultMeetingCount' => 10, - 'DefaultChangeDepth' => 5, - 'DefaultDistanceUnits' => 'mi', - 'DefaultDurationTime' => '01:30:00', - 'DurationTextInitialText' => 'N.A. Meetings are usually 90 minutes long (an hour and a half), unless otherwise indicated.', - 'time_format' => 'g:i A', - 'change_date_format' => 'g:i A, n/j/Y', - 'BannerTextInitialText' => 'Administration Login', - 'TitleTextInitialText' => 'Basic Meeting List Toolbox Administration', - 'DefaultRegionBias' => 'us', - 'search_spec_map_center' => array ( 'longitude' => -118.563659, 'latitude' => 34.235918, 'zoom' => 6 ), - 'DistanceChoices' => array ( 2, 5, 10, 20, 50 ), - 'HistoryChoices' => array ( 1, 2, 3, 5, 8, 10, 15 ), - 'PW_LengthChices' => array ( 6, 8, 10, 12, 16 ), - 'ServerAdminDefaultLogin' => 'serveradmin', - - 'Explanatory_Text_1_Initial_Intro' => 'This install wizard will guide you through the process of creating an initial database, as well as a configuration file. In the final step, we will create a settings file, and initialize an empty database.', - 'Explanatory_Text_1_DB_Intro' => 'The first thing that you need to do, is create a new, EMPTY database, and a database user that has full access to that database. This is usually done via your Web site Control Panel. Once you have created the database, you need to enter the information about that database into the text items on this page.', - - 'Explanatory_Text_2_Region_Bias_Intro' => 'The "Region Bias" is a code that is sent to Google when a location search is done, and can help Google to make sense of ambiguous search queries.', - 'Explanatory_Text_2_API_key_Intro' => 'The "API Key" is a key that you need to register with Google in order to be able to use their mapping service.', - 'Explanatory_Text_2_API_key_2_Intro' => 'You will need to provide a valid API Key in order to create new meetings in the Root Server.', - - 'Explanatory_Text_3_Server_Admin_Intro' => 'The Server Administrator is the main user for the server. It is the only account that can create new users and Service bodies, and is very powerful. You should create a login ID and a non-trivial password for this account. You\'ll be able to modify the other aspects of the account on the main server, once the database has been set up.', - 'Explanatory_Text_3_Misc_Intro' => 'These are various settings that affect how the root server behaves and appears.', - - 'Explanatory_Text_4_Main_Intro' => 'If you have entered the database information, provided a valid Google Maps API Key, and specified the login information for the Server Administrator, then you can initialize the root server here. Remember that the database must be COMPLETELY EMPTY of BMLT Root Server tables for this server (It can have tables for other servers or services).', - 'Explanatory_Text_4_NAWS_Export' => 'Optionally, you can import the meetings from a NAWS export spreadsheet. Uncheck the box to initialize them to \'unpublished\'. (This is useful if many of the new meetings will need to be edited or deleted, and you don\'t want them showing up in the meantime.)', - 'Explanatory_Text_4_File_Intro' => 'The text in the box below is the PHP source code for the main settings file. You will need to create a file on the server with this text in it. The file is at the same level as the main server directory for the root server.', - 'Explanatory_Text_4_File_Extra' => 'You also need to make sure that the file permissions are restricted (chmod 0644). This prevents the file from being written, and the root server will not run unless the file has the correct permissions.', - 'Page_4_PathInfo' => 'The file needs to be placed as %s/auto-config.inc.php, which is where your %s directory is. After the file has been created and you have put the above text into it, you should execute the following command to make sure that the permissions are correct:', - 'Page_4_Final' => 'Once all this is complete, refresh this page, and you should see the root server login page.', - 'FormatLangNamesLabel' => 'Enter extra languages in format code1:name1 (example "fa:farsi ru:russian"):', - ); diff --git a/src/legacy/local_server/server_admin/lang/en/name.txt b/src/legacy/local_server/server_admin/lang/en/name.txt deleted file mode 100755 index 3d38949de..000000000 --- a/src/legacy/local_server/server_admin/lang/en/name.txt +++ /dev/null @@ -1 +0,0 @@ -English \ No newline at end of file diff --git a/src/legacy/local_server/server_admin/lang/en/server_admin_strings.inc.php b/src/legacy/local_server/server_admin/lang/en/server_admin_strings.inc.php deleted file mode 100755 index bdc1f66f0..000000000 --- a/src/legacy/local_server/server_admin/lang/en/server_admin_strings.inc.php +++ /dev/null @@ -1,494 +0,0 @@ -. */ - -defined('BMLT_EXEC') or die('Cannot Execute Directly'); // Makes sure that this file is in the correct context. - -$comdef_server_admin_strings = array( - 'server_admin_disclosure' => 'Server Administration', - 'server_admin_naws_spreadsheet_label' => 'Updated World Committee Codes Spreadsheet:', - 'update_world_ids_button_text' => 'Update World Committee Codes', - 'update_world_ids_from_spreadsheet_dropdown_text' => 'Update World Committee Codes (Group IDs from NAWS) from NAWS Spreadsheet', - 'server_admin_error_no_world_ids_updated' => 'No World IDs were updated. This could be because your user does not have permission to update the submitted meetings.', - 'server_admin_error_required_spreadsheet_column' => 'Required column does not exist in the spreadsheet: ', - 'server_admin_error_bmlt_id_not_integer' => 'The provided bmlt_id is not an integer: ', - 'server_admin_error_could_not_create_reader' => 'Could not create reader for file: ', - 'server_admin_error_no_files_uploaded' => 'No files were uploaded.', - 'server_admin_error_service_bodies_already_exist' => 'Service bodies with the following World IDs already exist: ', - 'server_admin_error_meetings_already_exist' => 'Meetings with the following World IDs already exist: ', - 'server_admin_ui_num_meetings_updated' => 'Number of meetings updated: ', - 'server_admin_ui_num_meetings_not_updated' => 'Number of meetings that did not need updating: ', - 'server_admin_ui_warning' => 'WARNING', - 'server_admin_ui_errors' => 'Error(s)', - 'server_admin_ui_deleted_meetings_marked' => 'Number of deleted meetings marked so that they won\'t appear in future NAWS exports: ', - 'server_admin_ui_problem_meetings' => 'meetings were found in the spreadsheet that couldn\'t be updated. Problem meeting IDs: ', - 'server_admin_ui_service_bodies_created' => 'Service bodies created: ', - 'server_admin_ui_meetings_created' => 'Meetings created: ', - 'server_admin_ui_users_created' => 'Users created: ', - 'server_admin_ui_refresh_ui_text' => 'Sign out and then sign in again to see the new service bodies, users, and meetings.', - 'import_service_bodies_and_meetings_button_text' => 'Import Service Bodies and Meetings', - 'import_service_bodies_and_meetings_dropdown_text' => 'Import Service Bodies and Meetings from NAWS Export', - 'server_admin_naws_import_spreadsheet_label' => 'NAWS Import Spreadsheet: ', - 'server_admin_naws_import_initially_publish' => 'Initialize imported meetings to \'published\': ', - 'server_admin_naws_import_explanation' => 'Uncheck the box to initialize imported meetings to \'unpublished\'. (This is useful if many of the new meetings will need to be edited or deleted, and you don\'t want them showing up in the meantime.)', - 'account_disclosure' => 'My Account', - 'account_name_label' => 'My Account Name:', - 'account_login_label' => 'My Login:', - 'account_type_label' => 'I Am A:', - 'account_type_1' => 'Server Administrator', - 'account_type_2' => 'Service Body Administrator', - 'ServerMapsURL' => 'https://maps.googleapis.com/maps/api/geocode/xml?address=##SEARCH_STRING##&sensor=false', - 'account_type_4' => 'Pathetic Luser Who Shouldn\'t Even Have Access to This Page -The Author of the Software Pooched it BAD!', - 'account_type_5' => 'Service Body Observer', - 'change_password_label' => 'Change My Password To:', - 'change_password_default_text' => 'Leave This Alone If You Don\'t Want To Change Your Password', - 'account_email_label' => 'My Email Address:', - 'email_address_default_text' => 'Enter An Email Address', - 'account_description_label' => 'My Description:', - 'account_description_default_text' => 'Enter A Description', - 'account_change_button_text' => 'Change My Account Settings', - 'account_change_fader_success_text' => 'The Account Information Was Successfully Changed', - 'account_change_fader_failure_text' => 'The Account Information Was Not Changed', - 'meeting_editor_disclosure' => 'Meeting Editor', - 'meeting_editor_already_editing_confirm' => 'You are currently editing another meeting. Do you want to lose all changes in that meeting?', - 'meeting_change_fader_success_text' => 'The Meeting Was Successfully Changed', - 'meeting_change_fader_failure_text' => 'The Meeting Was Not Changed', - 'meeting_change_fader_success_delete_text' => 'The Meeting Was Successfully Deleted', - 'meeting_change_fader_fail_delete_text' => 'The Meeting Was Not Deleted', - 'meeting_change_fader_success_add_text' => 'The New Meeting Was Successfully Added', - 'meeting_change_fader_fail_add_text' => 'The New Meeting Was Not Added', - 'meeting_text_input_label' => 'Search For Text:', - 'access_service_body_label' => 'I Have Access to:', - 'meeting_text_input_default_text' => 'Enter Some Search Text', - 'meeting_text_location_label' => 'This is a Location or PostCode', - 'meeting_search_weekdays_label' => 'Search For Selected Weekdays:', - 'meeting_search_weekdays_names' => array('All', 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'), - 'meeting_search_service_bodies_label' => 'Search In Selected Service Bodies:', - 'meeting_search_start_time_label' => 'Search By Meeting Start Time:', - 'meeting_search_start_time_all_label' => 'Any Time', - 'meeting_search_start_time_morn_label' => 'Morning', - 'meeting_search_start_time_aft_label' => 'Afternoon', - 'meeting_search_start_time_eve_label' => 'Evening', - 'meeting_search_no_results_text' => 'No Meetings Found', - 'meeting_editor_tab_specifier_text' => 'Search For Meetings', - 'meeting_editor_tab_editor_text' => 'Edit Or Create Meetings', - 'meeting_editor_create_new_text' => 'Create A New Meeting', - 'meeting_editor_location_map_link' => 'Location Map', - 'meeting_editor_screen_match_ll_button' => 'Set Longitude and Latitude to Address', - 'meeting_editor_screen_default_text_prompt' => 'Enter Some Text or a Number', - 'meeting_is_published' => 'Meeting is Published', - 'meeting_unpublished_note' => 'Note: Unpublishing a meeting indicates a temporary closure. If this meeting has closed permanently, please delete it.', - 'meeting_editor_screen_meeting_name_label' => 'Meeting Name:', - 'meeting_editor_screen_meeting_name_prompt' => 'Enter A Meeting Name', - 'meeting_editor_screen_meeting_weekday_label' => 'Weekday:', - 'meeting_editor_screen_meeting_start_label' => 'Meeting Start Time:', - 'meeting_editor_screen_meeting_time_zone_label' => 'Meeting Time Zone:', - 'meeting_editor_screen_meeting_am_label' => 'AM', - 'meeting_editor_screen_meeting_pm_label' => 'PM', - 'meeting_editor_screen_meeting_noon_label' => 'Noon', - 'meeting_editor_screen_meeting_midnight_label' => 'Midnight', - 'meeting_editor_screen_meeting_duration_label' => 'Duration:', - 'meeting_editor_screen_meeting_oe_label' => 'Open-Ended', - 'meeting_editor_screen_meeting_cc_label' => 'World Committee Code:', - 'meeting_editor_screen_meeting_cc_advice' => 'Normally leave this field alone (see documentation).', - 'meeting_editor_screen_meeting_contact_label' => 'Meeting Email Contact:', - 'meeting_editor_screen_meeting_contact_prompt' => 'Enter An Email for A Contact Specific Only to This Meeting', - 'meeting_editor_screen_meeting_sb_label' => 'Service Body:', - 'meeting_editor_screen_meeting_sb_default_value' => 'No Service Body Selected', - 'meeting_editor_screen_meeting_longitude_label' => 'Longitude:', - 'meeting_editor_screen_meeting_longitude_prompt' => 'Enter A Longitude', - 'meeting_editor_screen_meeting_latitude_label' => 'Latitude:', - 'meeting_editor_screen_meeting_latitude_prompt' => 'Enter A Latitude', - 'meeting_editor_screen_meeting_location_label' => 'Location:', - 'meeting_editor_screen_meeting_location_prompt' => 'Enter A Location Name (Like a Building Name)', - 'meeting_editor_screen_meeting_info_label' => 'Extra Info:', - 'meeting_editor_screen_meeting_info_prompt' => 'Enter Any Additional Location Information', - 'meeting_editor_screen_meeting_street_label' => 'Street Address:', - 'meeting_editor_screen_meeting_street_prompt' => 'Enter A Street Address', - 'meeting_editor_screen_meeting_neighborhood_label' => 'Neighborhood:', - 'meeting_editor_screen_meeting_neighborhood_prompt' => 'Enter A Neighborhood (Not Borough or City Subsection)', - 'meeting_editor_screen_meeting_borough_label' => 'Borough/City Subsection:', - 'meeting_editor_screen_meeting_borough_prompt' => 'Enter A Borough or City Subsection (Not Neighborhood)', - 'meeting_editor_screen_meeting_city_label' => 'City/Town:', - 'meeting_editor_screen_meeting_city_prompt' => 'Enter A City or Town Name (Not County or Borough)', - 'meeting_editor_screen_meeting_county_label' => 'County/Sub-Province:', - 'meeting_editor_screen_meeting_county_prompt' => 'Enter A County or Sub-Province Name', - 'meeting_editor_screen_meeting_state_label' => 'State/Province:', - 'meeting_editor_screen_meeting_state_prompt' => 'Enter A State or Province Name', - 'meeting_editor_screen_meeting_zip_label' => 'Zip Code/Postal Code:', - 'meeting_editor_screen_meeting_zip_prompt' => 'Enter A Postal Code', - 'meeting_editor_screen_meeting_nation_label' => 'Nation:', - 'meeting_editor_screen_meeting_nation_prompt' => 'Enter The Nation Name', - 'meeting_editor_screen_meeting_comments_label' => 'Comments:', - 'meeting_editor_screen_meeting_train_lines_label' => 'Train Lines:', - 'meeting_editor_screen_meeting_bus_lines_label' => 'Bus Lines:', - 'meeting_editor_screen_meeting_phone_meeting_number_label' => 'Phone Meeting Dial-in Number:', - 'meeting_editor_screen_meeting_phone_meeting_number_prompt' => 'Enter the dial-in number for a phone or virtual meeting', - 'meeting_editor_screen_meeting_virtual_meeting_link_label' => 'Virtual Meeting Link:', - 'meeting_editor_screen_meeting_virtual_meeting_link_prompt' => 'Enter the link for a virtual meeting', - 'meeting_editor_screen_meeting_virtual_meeting_additional_info_label' => 'Virtual Meeting Additional Information:', - 'meeting_editor_screen_meeting_virtual_meeting_additional_info_prompt' => 'Enter any additional information for joining the virtual meeting, including directly from the app. For example, if the meeting uses Zoom, "Zoom ID: 456 033 8613, Passcode: 1953" would be appropriate.', - 'meeting_editor_screen_meeting_venue_type' => 'Venue Type:', - 'meeting_editor_screen_meeting_venue_type_inperson' => 'In-Person', - 'meeting_editor_screen_meeting_venue_type_virtual' => 'Virtual', - 'meeting_editor_screen_meeting_venue_type_virtualTC' => 'Virtual (temporarily replacing an in-person)', - 'meeting_editor_screen_meeting_venue_type_hybrid' => 'Hybrid (both in-person and virtual)', - 'meeting_editor_screen_meeting_venue_type_validation' => 'You must select a venue type.', - 'meeting_editor_screen_meeting_virtual_info_missing' => 'Virtual or hybrid meetings must have a Virtual Meeting Link, a Phone Meeting Dial-in Number, or Virtual Meeting Additional Information', - 'meeting_editor_screen_meeting_format_radio_not_selected' => 'You must select one format from the group ${radioDescription}.', - 'meeting_editor_screen_meeting_location_warning' => 'Meeting should have a location (at least a city/town and state/province, or a zip/postal code).', - 'meeting_editor_screen_meeting_address_warning' => 'In-person or hybrid meetings should have a street address.', - 'meeting_editor_screen_meeting_url_validation' => 'Virtual Meeting Link is not a valid URL.', - 'meeting_editor_screen_meeting_url_or_phone_warning' => 'Virtual or hybrid meetings should have either a Virtual Meeting Link or a Phone Meeting Dial-in Number', - 'meeting_editor_screen_meeting_additional_warning' => 'Please also fill in Virtual Meeting Additional Information if there is a Virtual Meeting Link.', - 'meeting_editor_screen_in_person_virtual_info_warning' => 'In-person meetings shouldn\'t have any virtual meeting information.', - 'meeting_editor_screen_meeting_virtual_location_info_warning' => 'Virtual meetings shouldn\'t have a location name or address.', - 'meeting_editor_screen_meeting_validation_warning' => 'There are warnings. Are you sure you want to save anyway? If not, press \'cancel\' and go to the Location tab to see the warnings in place and address them.', - 'meeting_editor_screen_meeting_validation_failed' => 'Unable to save due to input errors. Please go to the Location tab to address them, and then retry saving. Errors: ', - 'meeting_editor_screen_meeting_validation_warnings' => 'Input warnings shown on the Location tab: ', - 'meeting_editor_screen_meeting_contact_name_1_label' => 'Contact 1 Name:', - 'meeting_editor_screen_meeting_contact_email_1_label' => 'Contact 1 Email:', - 'meeting_editor_screen_meeting_contact_phone_1_label' => 'Contact 1 Phone:', - 'meeting_editor_screen_meeting_contact_name_2_label' => 'Contact 2 Name:', - 'meeting_editor_screen_meeting_contact_email_2_label' => 'Contact 2 Email:', - 'meeting_editor_screen_meeting_contact_phone_2_label' => 'Contact 2 Phone:', - 'meeting_editor_screen_meeting_publish_search_prompt' => 'Look For:', - 'meeting_editor_screen_meeting_publish_search_pub' => 'Published Meetings Only', - 'meeting_editor_screen_meeting_publish_search_unpub' => 'Unpublished Meetings Only', - 'meeting_editor_screen_meeting_visibility_advice' => 'This is never displayed in normal meeting searches.', - 'meeting_editor_screen_meeting_publish_search_all' => 'All Meetings', - 'meeting_editor_screen_meeting_create_button' => 'Create A New Meeting', - 'meeting_editor_screen_delete_button' => 'Delete This Meeting', - 'meeting_editor_screen_delete_button_confirm' => 'Are you sure that you want to delete this meeting?', - 'meeting_editor_screen_cancel_button' => 'Cancel', - 'logout' => 'Sign Out', - 'meeting_editor_screen_cancel_confirm' => 'Are you sure that you want to cancel editing this meeting, and lose all changes?', - 'meeting_lookup_failed' => 'The address lookup failed.', - 'meeting_lookup_failed_not_enough_address_info' => 'There is not enough valid address information to do a lookup.', - 'meeting_create_button_name' => 'Save This As A New Meeting', - 'meeting_saved_as_a_copy' => 'Save This Meeting As A Copy (Creates A New Meeting)', - 'meeting_save_buttonName' => 'Save the Changes to This Meeting', - 'meeting_editor_tab_bar_basic_tab_text' => 'Basic', - 'meeting_editor_tab_bar_location_tab_text' => 'Location', - 'meeting_editor_tab_bar_format_tab_text' => 'Format', - 'meeting_editor_tab_bar_other_tab_text' => 'Other', - 'meeting_editor_tab_bar_history_tab_text' => 'History', - 'meeting_editor_result_count_format' => '%d Meetings Found', - 'meeting_id_label' => 'Meeting ID:', - 'meeting_editor_default_zoom' => '13', - 'meeting_editor_default_weekday' => '2', - 'meeting_editor_default_start_time' => '20:30:00', - 'login_banner' => 'Basic Meeting List Toolbox', - 'login_underbanner' => 'Root Server Administration Console', - 'login' => 'Login ID', - 'password' => 'Password', - 'button' => 'Log In', - 'cookie' => 'You must enable cookies in order to administer this server.', - 'noscript' => 'You cannot administer this site without JavaScript.', - 'title' => 'Please log in to administer the server.', - 'edit_Meeting_object_not_found' => 'ERROR: The meeting was not found.', - 'edit_Meeting_object_not_changed' => 'ERROR: The meeting was not changed.', - 'edit_Meeting_auth_failure' => 'You are not authorized to edit this meeting.', - 'not_auth_1' => 'NOT AUTHORIZED', - 'not_auth_2' => 'You are not authorized to administer this server.', - 'not_auth_3' => 'There was a problem with the user name or password that you entered.', - 'email_format_bad' => 'The email address that you entered was not formatted correctly.', - 'history_header_format' => '
%sby %s
', - 'history_no_history_available_text' => '

No History Available For This Meeting

', - 'service_body_editor_disclosure' => 'Service Body Administration', - 'service_body_change_fader_success_text' => 'The Service Body Was Successfully Changed', - 'service_body_change_fader_fail_text' => 'The Service Body Change Failed', - 'service_body_editor_screen_sb_id_label' => 'ID:', - 'service_body_editor_screen_sb_name_label' => 'Name:', - 'service_body_name_default_prompt_text' => 'Enter the Name of This Service Body', - 'service_body_parent_popup_label' => 'Service Body Parent:', - 'service_body_parent_popup_no_parent_option' => 'No Parent (Top-Level)', - 'service_body_editor_screen_sb_admin_user_label' => 'Primary Admin:', - 'service_body_editor_screen_sb_admin_description_label' => 'Description:', - 'service_body_description_default_prompt_text' => 'Enter A Description of This Service Body', - 'service_body_editor_screen_sb_admin_email_label' => 'Contact Email:', - 'service_body_email_default_prompt_text' => 'Enter A Contact Email Address for This Service Body', - 'service_body_editor_screen_sb_admin_uri_label' => 'Web Site URL:', - 'service_body_uri_default_prompt_text' => 'Enter A Web Site URL for This Service Body', - 'service_body_editor_screen_sb_admin_full_editor_label' => 'Full Meeting List Editors:', - 'service_body_editor_screen_sb_admin_full_editor_desc' => 'These Users Can Edit Any Meetings In This Service Body.', - 'service_body_editor_screen_sb_admin_editor_label' => 'Basic Meeting List Editors:', - 'service_body_editor_screen_sb_admin_editor_desc' => 'These Users Can Edit Any Meetings In This Service Body, But Only If They Are Unpublished.', - 'service_body_editor_screen_sb_admin_observer_label' => 'Observers:', - 'service_body_editor_screen_sb_admin_observer_desc' => 'These Users Can See Hidden Info (Like Email Addresses), But Cannot Edit Anything.', - 'service_body_dirty_confirm_text' => 'You have made changes to this Service Body. Do you want to lose your changes?', - 'service_body_save_button' => 'Save These Service Body Changes', - 'service_body_create_button' => 'Create This Service Body', - 'service_body_delete_button' => 'Delete This Service Body', - 'service_body_delete_perm_checkbox' => 'Delete This Service Body Permanently', - 'service_body_delete_button_confirm' => 'Are you sure that you want to delete this Service body? Make sure that all meetings are either removed or transferred to another service body before performing this function.', - 'service_body_delete_button_confirm_perm' => 'This Service body will be deleted permanently!', - 'service_body_change_fader_create_success_text' => 'The Service Body Was Successfully Created', - 'service_body_change_fader_create_fail_text' => 'The Service Body Create Failed', - 'service_body_change_fader_delete_success_text' => 'The Service Body Was Successfully Deleted', - 'service_body_change_fader_delete_fail_text' => 'The Service Body Delete Failed', - 'service_body_change_fader_fail_no_data_text' => 'The Service Body Change Failed, Because There Was No Data Supplied', - 'service_body_change_fader_fail_cant_find_sb_text' => 'The Service Body Change Failed, Because The Service Body Was Not Found', - 'service_body_change_fader_fail_cant_update_text' => 'The Service Body Change Failed, Because The Service Body Was Not Updated', - 'service_body_change_fader_fail_bad_hierarchy' => 'The Service Body Change Failed, Because The Selected Owner Service Body Is Under This Service Body, And Cannot Be Used', - 'service_body_cancel_button' => 'Restore To Original', - 'service_body_editor_type_label' => 'Service Body Type:', - 'service_body_editor_type_c_comdef_service_body__GRP__' => 'Group', - 'service_body_editor_type_c_comdef_service_body__COP__' => 'Co-Op', - 'service_body_editor_type_c_comdef_service_body__ASC__' => 'Area Service Committee', - 'service_body_editor_type_c_comdef_service_body__RSC__' => 'Regional Service Conference', - 'service_body_editor_type_c_comdef_service_body__WSC__' => 'World Service Conference', - 'service_body_editor_type_c_comdef_service_body__MAS__' => 'Metro Area', - 'service_body_editor_type_c_comdef_service_body__ZFM__' => 'Zonal Forum', - 'service_body_editor_type_c_comdef_service_body__GSU__' => 'Group Service Unit', - 'service_body_editor_type_c_comdef_service_body__LSU__' => 'Local Service Unit', - 'service_body_editor_screen_helpline_label' => 'Helpline:', - 'service_body_editor_screen_helpline_prompt' => 'Enter The Helpline Telephone Number', - 'service_body_editor_uri_naws_format_text' => 'Get The Meetings For This Service Body As A NAWS-Compatible File', - 'edit_Meeting_meeting_id' => 'Meeting ID:', - 'service_body_editor_create_new_sb_option' => 'Create A New Service Body', - 'service_body_editor_screen_world_cc_label' => 'World Committee Code:', - 'service_body_editor_screen_world_cc_prompt' => 'Enter A World Committee Code', - 'user_editor_disclosure' => 'User Administration', - 'user_editor_create_new_user_option' => 'Create A New User', - 'user_editor_screen_sb_id_label' => 'ID:', - 'user_editor_account_login_label' => 'User Login:', - 'user_editor_login_default_text' => 'Enter the User Login', - 'user_editor_account_type_label' => 'User Is A:', - 'user_editor_user_owner_label' => 'Owned By: ', - 'user_editor_account_type_1' => 'Server Administrator', - 'user_editor_account_type_2' => 'Service Body Administrator', - 'user_editor_account_type_3' => 'Service Body Editor', - 'user_editor_account_type_5' => 'Service Body Observer', - 'user_editor_account_type_4' => 'Disabled User', - 'user_editor_account_name_label' => 'User Name:', - 'user_editor_name_default_text' => 'Enter the User Name', - 'user_editor_account_description_label' => 'Description:', - 'user_editor_description_default_text' => 'Enter the User Description', - 'user_editor_account_email_label' => 'Email:', - 'user_editor_email_default_text' => 'Enter the User Email', - 'user_change_fader_success_text' => 'The User Was Successfully Changed', - 'user_change_fader_fail_text' => 'The User Change Failed', - 'user_change_fader_create_success_text' => 'The User Was Successfully Created', - 'user_change_fader_create_fail_text' => 'The User Create Failed', - 'user_change_fader_create_fail_already_exists' => 'A Login For The User That You Are Trying To Create Already Exists.', - 'user_change_fader_delete_success_text' => 'The User Was Successfully Deleted', - 'user_change_fader_delete_fail_text' => 'The User Delete Failed', - 'user_save_button' => 'Save the Changes to This User', - 'user_create_button' => 'Create This New User', - 'user_cancel_button' => 'Restore To Original', - 'user_delete_button' => 'Delete This User', - 'user_delete_perm_checkbox' => 'Delete This User Permanently', - 'user_password_label' => 'Change Password To:', - 'user_new_password_label' => 'Set Password To:', - 'user_password_default_text' => 'Leave This Alone, Unless You Want To Change The Password', - 'user_new_password_default_text' => 'You Must Enter A Password For A new User', - 'user_dirty_confirm_text' => 'You have made changes to this User. Do you want to lose your changes?', - 'user_delete_button_confirm' => 'Are you sure that you want to delete this user?', - 'user_delete_button_confirm_perm' => 'This user will be deleted permanently!', - 'user_create_password_alert_text' => 'New users must have a password. You have not supplied a password for this user.', - 'user_change_fader_fail_no_data_text' => 'The User Change Failed, Because There Was No Data Supplied', - 'user_change_fader_fail_cant_find_sb_text' => 'The User Change Failed, Because The User Was Not Found', - 'user_change_fader_fail_cant_update_text' => 'The User Change Failed, Because The User Was Not Updated', - 'format_editor_disclosure' => 'Format Administration', - 'format_change_fader_change_success_text' => 'The Format Was Successfully Changed', - 'format_change_fader_change_fail_text' => 'The Format Change Failed', - 'format_change_fader_create_success_text' => 'The Format Was Successfully Created', - 'format_change_fader_create_fail_text' => 'The Format Create Failed', - 'format_change_fader_delete_success_text' => 'The Format Was Successfully Deleted', - 'format_change_fader_delete_fail_text' => 'The Format Delete Failed', - 'format_change_fader_fail_no_data_text' => 'The Format Change Failed, Because There Was No Data Supplied', - 'format_change_fader_fail_cant_find_sb_text' => 'The Format Change Failed, Because The Format Was Not Found', - 'format_change_fader_fail_cant_update_text' => 'The Format Change Failed, Because The Format Was Not Updated', - 'format_editor_name_default_text' => 'Enter A Very Short Description', - 'format_editor_description_default_text' => 'Enter A More Detailed Description', - 'format_editor_create_format_button_text' => 'Create New Format', - 'format_editor_cancel_create_format_button_text' => 'Cancel', - 'format_editor_create_this_format_button_text' => 'Create This Format', - 'format_editor_change_format_button_text' => 'Change This Format', - 'format_editor_delete_format_button_text' => 'Delete This Format', - 'format_editor_reset_format_button_text' => 'Restore To Original', - 'need_refresh_message_fader_text' => 'You Should Refresh This Page Before Using This Section', - 'need_refresh_message_alert_text' => 'Because you have made changes in the Server Administration, Service Body Administration, User Administration, or Format Administration, the information displayed in this section may no longer be accurate, so the page needs to be refreshed. The easiest way to do this, is to Sign Out, then Log In again.', - 'format_editor_delete_button_confirm' => 'Are you sure that you want to delete this format?', - 'format_editor_delete_button_confirm_perm' => 'This format will be deleted permanently!', - 'format_editor_missing_key' => 'This format should have an entry for every language (at least a key).', - 'format_editor_reserved_key' => 'This key is reserved for a venue type format - please use something different.', - 'min_password_length_string' => 'The password is too short! It must be at least %d characters long!', - 'AJAX_Auth_Failure' => 'Authorization failed for this operation. There may be a problem with the server configuration.', - 'Maps_API_Key_Warning' => 'There is a problem with the Google Maps API Key.', - 'Maps_API_Key_Not_Set' => 'The Google Maps API key is not set.', - 'Observer_Link_Text' => 'Meeting Browser', - 'Data_Transfer_Link_Text' => 'Import Meeting Data (WARNING: Replaces Current Data!)', - 'MapsURL' => 'https://maps.google.com/maps?q=##LAT##,##LONG##+(##NAME##)&ll=##LAT##,##LONG##', - 'hidden_value' => 'Cannot Display Data -Unauthorized', - 'Value_Prompts' => array( - 'id_bigint' => 'Meeting ID', - 'worldid_mixed' => 'World Services ID', - 'service_body' => 'Service Body', - 'service_bodies' => 'Service Bodies', - 'weekdays' => 'Weekdays', - 'weekday' => 'Meeting Gathers Every', - 'start_time' => 'Meeting Starts at', - 'duration_time' => 'Meeting Lasts', - 'location' => 'Location', - 'duration_time_hour' => 'Hour', - 'duration_time_hours' => 'Hours', - 'duration_time_minute' => 'Minute', - 'duration_time_minutes' => 'Minutes', - 'lang_enum' => 'Language', - 'formats' => 'Formats', - 'distance' => 'Distance from Center', - 'generic' => 'NA Meeting', - 'close_title' => 'Close This Meeting Detail Window', - 'close_text' => 'Close Window', - 'map_alt' => 'Map to Meeting', - 'map' => 'Follow This Link for A Map', - 'title_checkbox_unpub_meeting' => 'This meeting is unpublished. It cannot be seen by regular searches.', - 'title_checkbox_copy_meeting' => 'This meeting is a duplicate of another meeting. It is also unpublished. It cannot be seen by regular searches.' - ), - 'world_format_codes_prompt' => 'NAWS Format:', - 'world_format_codes' => array( - '' => 'None', - 'OPEN' => 'Open', - 'CLOSED' => 'Closed', - 'WCHR' => 'Wheelchair-Accessible', - 'BEG' => 'Beginner/Newcomer', - 'BT' => 'Basic Text', - 'CAN' => 'Candlelight', - 'CPT' => '12 Concepts', - 'CW' => 'Children Welcome', - 'DISC' => 'Discussion/Participation', - 'GL' => 'Gay/Lesbian', - 'IP' => 'IP Study', - 'IW' => 'It Works Study', - 'JFT' => 'Just For Today Study', - 'LC' => 'Living Clean', - 'LIT' => 'Literature Study', - 'M' => 'Men', - 'MED' => 'Meditation', - 'NS' => 'Non-Smoking', - 'QA' => 'Questions & Answers', - 'RA' => 'Restricted Access', - 'S-D' => 'Speaker/Discussion', - 'SMOK' => 'Smoking', - 'SPK' => 'Speaker', - 'STEP' => 'Step', - 'SWG' => 'Step Working Guide Study', - 'TOP' => 'Topic', - 'TRAD' => 'Tradition', - 'VAR' => 'Format Varies', - 'W' => 'Women', - 'Y' => 'Young People', - 'LANG' => 'Alternate Language', - 'GP' => 'Guiding Principles', - 'NC' => 'No Children', - 'CH' => 'Closed Holidays', - 'VM' => 'Virtual', - 'HYBR' => 'Virtual and In-Person', - 'TC' => 'Temporarily Closed Facility', - 'SPAD' => 'Spiritual Principle a Day', - ), - 'format_type_prompt' => 'Format Type:', - 'format_type_codes' => array( - '' => 'None', - 'FC1' => 'Meeting Format (Speaker, Book Study, etc.)', - 'FC2' => 'Location Code (Wheelchair Accessible, Limited Parking, etc.)', - 'FC3' => 'Common Needs and Restrictions (Mens Meeting, LGTBQ, No Children, etc.)', - 'O' => 'Attendance by non-addicts (Open, Closed)', - 'LANG' => 'Language', - 'ALERT' => 'Format should be especially prominent (Clean requirement, etc.)', - ), - 'unknown_format_type' => 'Format Type: ', - 'other_or_empty_format_type' => 'Other or empty format type', - 'cookie_monster' => 'This site uses a cookie to store your preferred language.', - 'main_prompts' => array( - 'id_bigint' => 'ID', - 'worldid_mixed' => 'World ID', - 'shared_group_id_bigint' => 'Unused', - 'service_body_bigint' => 'Service Body ID', - 'weekday_tinyint' => 'Weekday', - 'venue_type' => 'Venue Type', - 'start_time' => 'Start Time', - 'duration_time' => 'Duration', - 'time_zone' => 'Time Zone', - 'formats' => 'Formats', - 'lang_enum' => 'Language', - 'longitude' => 'Longitude', - 'latitude' => 'Latitude', - 'published' => 'Published', - 'email_contact' => 'Email Contact', - ), - 'check_all' => 'Check All', - 'uncheck_all' => 'Uncheck All', - 'automatically_calculated_on_save' => 'Automatically calculated on save.' -); - -$email_contact_strings = array( - 'meeting_contact_form_subject_format' => "[MEETING LIST CONTACT] %s", - 'meeting_contact_message_format' => "%s\n--\nThis message concerns the meeting named \"%s\", which meets at %s, on %s.\nBrowser Link: %s\nEdit Link: %s\nIt was sent directly from the meeting list web server, and the sender is not aware of your email address.\nPlease be aware that replying will expose your email address.\nIf you use \"Reply All\", and there are multiple email recipients, you may expose other people's email addresses.\nPlease respect people's privacy and anonymity; including the original sender of this message." -); - -$change_type_strings = array( - '__THE_MEETING_WAS_CHANGED__' => 'The meeting was changed.', - '__THE_MEETING_WAS_CREATED__' => 'The meeting was created.', - '__THE_MEETING_WAS_DELETED__' => 'The meeting was deleted.', - '__THE_MEETING_WAS_ROLLED_BACK__' => 'The meeting was rolled back to a previous version.', - - '__THE_FORMAT_WAS_CHANGED__' => 'The format was changed.', - '__THE_FORMAT_WAS_CREATED__' => 'The format was created.', - '__THE_FORMAT_WAS_DELETED__' => 'The format was deleted.', - '__THE_FORMAT_WAS_ROLLED_BACK__' => 'The format was rolled back to a previous version.', - - '__THE_SERVICE_BODY_WAS_CHANGED__' => 'The service body was changed.', - '__THE_SERVICE_BODY_WAS_CREATED__' => 'The service body was created.', - '__THE_SERVICE_BODY_WAS_DELETED__' => 'The service body was deleted.', - '__THE_SERVICE_BODY_WAS_ROLLED_BACK__' => 'The service body was rolled back to a previous version.', - - '__THE_USER_WAS_CHANGED__' => 'The user was changed.', - '__THE_USER_WAS_CREATED__' => 'The user was created.', - '__THE_USER_WAS_DELETED__' => 'The user was deleted.', - '__THE_USER_WAS_ROLLED_BACK__' => 'The user was rolled back to a previous version.', - - '__BY__' => 'by', - '__FOR__' => 'for' -); - -$detailed_change_strings = array( - 'was_changed_from' => 'was changed from', - 'to' => 'to', - 'was_changed' => 'was changed', - 'was_added_as' => 'was added as', - 'was_deleted' => 'was deleted', - 'was_published' => 'The meeting was published', - 'was_unpublished' => 'The meeting was unpublished', - 'formats_prompt' => 'The meeting format', - 'duration_time' => 'The meeting duration', - 'start_time' => 'The meeting start time', - 'longitude' => 'The meeting longitude', - 'latitude' => 'The meeting latitude', - 'sb_prompt' => 'The meeting changed its Service Body from', - 'id_bigint' => 'The meeting ID', - 'lang_enum' => 'The meeting language', - 'worldid_mixed' => 'The World Committee Code', - 'weekday_tinyint' => 'The day of the week on which the meeting gathers', - 'non_existent_service_body' => 'Service Body No Longer Exists', -); - -defined('_END_CHANGE_REPORT') or define('_END_CHANGE_REPORT', '.'); diff --git a/src/legacy/local_server/server_admin/lang/es/data_transfer_strings.php b/src/legacy/local_server/server_admin/lang/es/data_transfer_strings.php deleted file mode 100755 index 6fa2303ec..000000000 --- a/src/legacy/local_server/server_admin/lang/es/data_transfer_strings.php +++ /dev/null @@ -1,22 +0,0 @@ -.*/ - defined('BMLT_EXEC') or die('Cannot Execute Directly'); // Makes sure that this file is in the correct context. - - $comdef_data_transfer_strings = array (); diff --git a/src/legacy/local_server/server_admin/lang/es/install_wizard_strings.php b/src/legacy/local_server/server_admin/lang/es/install_wizard_strings.php deleted file mode 100755 index 6f2840948..000000000 --- a/src/legacy/local_server/server_admin/lang/es/install_wizard_strings.php +++ /dev/null @@ -1,139 +0,0 @@ -.*/ - defined('BMLT_EXEC') or die('Cannot Execute Directly'); // Makes sure that this file is in the correct context. - - global $comdef_install_wizard_strings; - - $comdef_install_wizard_strings = array ( - 'Database_Version_Error' => 'ERROR: You must have PHP Version 5.6 or greater installed on this server!', - 'Database_PDO_Error' => 'ERROR: You do not have PHP PDO installed!', - 'Database_Type_Error' => 'ERROR: Even though you have PDO, you have no database drivers installed!', - 'Database_TestButton_Text' => 'TEST', - 'Database_TestButton_Success' => 'The database connection was successful.', - 'Database_TestButton_Fail' => 'The database connection failed: ', - 'Database_TestButton_Fail2' => 'The database connection failed because there is already an initialized database.', - 'Database_Whitespace_Note' => 'Warning: %s has whitespace at the beginning or end.', - - 'AJAX_Handler_DB_Connect_Error' => 'The database connection failed! Please make sure that the database exists, IS COMPLETELY EMPTY, the user is created, and that user has full permissions on the empty database.', - 'AJAX_Handler_DB_Established_Error' => 'The database already exists, and has been set up! You cannot use this setup to overwrite an existing database!', - 'AJAX_Handler_DB_Incomplete_Error' => 'There is not enough information to initialize the database!', - - 'NoDatabase_Note_AlreadySet' => 'The database has already been initialized with the provided table prefix. Please choose a new one.', - 'NoDatabase_Note_PasswordIssue' => 'You must choose a username and password for the Server Administrator user.', - 'NoServerAdmin_Note_AlreadySet' => 'There is already an existing database, so you cannot set up a Server Administrator account (One already exists).', - 'NeedLongerPasswordNote' => 'This password is too short. It must be at least %d characters long.', - - 'Prev_Button' => 'PREVIOUS', - 'Next_Button' => 'NEXT', - - 'Page_1_Tab' => 'STEP 1: Database', - 'Page_1_Heading' => 'Database Connection Settings', - 'Page_1_Text' => 'Before you can apply the settings on this page, you must set up a new COMPLETELY EMPTY database, and create a database user that has full user rights on that database.', - - 'Database_Name' => 'Database Name:', - 'Database_Name_Default_Text' => 'Enter A Database Name', - 'Database_Type' => 'Database Type:', - 'Database_Host' => 'Database Host:', - 'Database_Host_Default_Text' => 'Enter A Database Host', - 'Database_Host_Additional_Text' => 'This is usually "localhost."', - 'Table_Prefix' => 'Table Prefix:', - 'Table_Prefix_Default_Text' => 'Enter A Table Prefix', - 'Table_Prefix_Additional_Text' => 'Only for multiple root servers sharing a database.', - 'Database_User' => 'Database User:', - 'Database_User_Default_Text' => 'Enter A Database User Name', - 'Database_PW' => 'Database Password:', - 'Database_PW_Default_Text' => 'Enter A Database Password', - 'Database_PW_Additional_Text' => 'Make this an ugly, difficult password. It has a great deal of power, and you will never need to remember it.', - - 'Maps_API_Key_Warning' => 'There is a problem with the Google Maps API Key.', - - 'Page_2_Tab' => 'STEP 2: Google Maps API', - 'Page_2_Heading' => 'Set The Initial Location For Meetings', - 'Page_2_Text' => 'When saving a meeting, the BMLT Root Server uses the Google Maps API to determine the latitude and longitude for the meeting address. These settings are required to allow the BMLT Root Server to communicate with the Google Maps API.', - - 'Page_3_Tab' => 'STEP 3: Server Settings', - 'Page_3_Heading' => 'Set Various Global Server Settings', - 'Page_3_Text' => 'These are a few settings that affect the administration and general configuration of this server. Most server settings are done in the server itself.', - 'Admin_Login' => 'Server Administrator Login:', - 'Admin_Login_Default_Text' => 'Enter A Server Administrator Login', - 'Admin_Login_Additional_Text' => 'This is the login string for the Server Administrator.', - 'Admin_Password' => 'Server Administrator Password:', - 'Admin_Password_Default_Text' => 'Enter A Server Administrator Password', - 'Admin_Password_Additional_Text' => 'Make sure that this is a non-trivial password! It has a great deal of power! (Also, don\'t forget it).', - 'ServerAdminName' => 'Server Administrator', - 'ServerAdminDesc' => 'Main Server Administrator', - 'ServerLangLabel' => 'Default Server Language:', - 'DistanceUnitsLabel' => 'Distance Units:', - 'DistanceUnitsMiles' => 'Miles', - 'DistanceUnitsKM' => 'Kilometres', - 'SearchDepthLabel' => 'Density of Meetings For Automatic Search:', - 'SearchDepthText' => 'This is an approximation of how many meetings need to be found in the automatic radius selection. More meetings means a bigger radius.', - 'HistoryDepthLabel' => 'How Many Meeting Changes To Save:', - 'HistoryDepthText' => 'The longer the history, the larger the database will become.', - 'TitleTextLabel' => 'The Title Of The Administration Screen:', - 'TitleTextDefaultText' => 'Enter A Short Title For the Editing Login Page', - 'BannerTextLabel' => 'Prompt For Administration Login:', - 'BannerTextDefaultText' => 'Enter A Short Prompt For The Login Page', - 'RegionBiasLabel' => 'Region Bias:', - 'PasswordLengthLabel' => 'Minimum Password Length:', - 'PasswordLengthExtraText' => 'This will also affect the Server Administrator password, above.', - 'DurationLabel' => 'Default Meeting Duration:', - 'DurationHourLabel' => 'Hours', - 'DurationMinutesLabel' => 'Minutes', - 'LanguageSelectorEnableLabel' => 'Display Language Selector On Login:', - 'LanguageSelectorEnableExtraText' => 'If you select this, a popup menu will appear in the login screen, so administrators can select their language.', - 'EmailContactEnableLabel' => 'Allow Email Contacts From Meetings:', - 'EmailContactEnableExtraText' => 'If you select this, site visitors will be able to send emails from meeting records.', - - 'Page_4_Tab' => 'STEP 4: Save The Settings', - 'Page_4_Heading' => 'Create the Settings File', - 'Page_4_Text' => 'The root server was unable to create the settings file for you. Instead, we ask you to create it yourself, via FTP or a control panel file manager, name it "auto-config.inc.php", and paste the following text into the file:', - - 'DefaultPasswordLength' => 10, - 'DefaultMeetingCount' => 10, - 'DefaultChangeDepth' => 5, - 'DefaultDistanceUnits' => 'mi', - 'DefaultDurationTime' => '01:30:00', - 'DurationTextInitialText' => 'N.A. Meetings are usually 90 minutes long (an hour and a half), unless otherwise indicated.', - 'time_format' => 'g:i A', - 'change_date_format' => 'g:i A, n/j/Y', - 'BannerTextInitialText' => 'Administration Login', - 'TitleTextInitialText' => 'Basic Meeting List Toolbox Administration', - 'DefaultRegionBias' => 'us', - 'search_spec_map_center' => array ( 'longitude' => -118.563659, 'latitude' => 34.235918, 'zoom' => 6 ), - 'DistanceChoices' => array ( 2, 5, 10, 20, 50 ), - 'HistoryChoices' => array ( 1, 2, 3, 5, 8, 10, 15 ), - 'PW_LengthChices' => array ( 6, 8, 10, 12, 16 ), - 'ServerAdminDefaultLogin' => 'serveradmin', - - 'Explanatory_Text_1_Initial_Intro' => 'This install wizard will guide you through the process of creating an initial database, as well as a configuration file. In the final step, we will create a settings file, and initialize an empty database.', - 'Explanatory_Text_1_DB_Intro' => 'The first thing that you need to do, is create a new, EMPTY database, and a database user that has full access to that database. This is usually done via your Web site Control Panel. Once you have created the database, you need to enter the information about that database into the text items on this page.', - - 'Explanatory_Text_2_Region_Bias_Intro' => 'The "Region Bias" is a code that is sent to Google when a location search is done, and can help Google to make sense of ambiguous search queries.', - - 'Explanatory_Text_3_Server_Admin_Intro' => 'The Server Administrator is the main user for the server. It is the only account that can create new users and Service bodies, and is very powerful. You should create a login ID and a non-trivial password for this account. You\'ll be able to modify the other aspects of the account on the main server, once the database has been set up.', - 'Explanatory_Text_3_Misc_Intro' => 'These are various settings that affect how the root server behaves and appears.', - - 'Explanatory_Text_4_Main_Intro' => 'If you have entered the database information, provided a valid Google Maps API Key, and specified the login information for the Server Administrator, then you can initialize the root server here. Remember that the database must be COMPLETELY EMPTY of BMLT Root Server tables for this server (It can have tables for other servers or services).', - 'Explanatory_Text_4_NAWS_Export' => 'Optionally, you can import the meetings from a NAWS export spreadsheet. Uncheck the box to initialize them to \'unpublished\'. (This is useful if many of the new meetings will need to be edited or deleted, and you don\'t want them showing up in the meantime.)', - 'Explanatory_Text_4_File_Intro' => 'The text in the box below is the PHP source code for the main settings file. You will need to create a file on the server with this text in it. The file is at the same level as the main server directory for the root server.', - 'Explanatory_Text_4_File_Extra' => 'You also need to make sure that the file permissions are restricted (chmod 0644). This prevents the file from being written, and the root server will not run unless the file has the correct permissions.', - 'Page_4_PathInfo' => 'The file needs to be placed as %s/auto-config.inc.php, which is where your %s directory is. After the file has been created and you have put the above text into it, you should execute the following command to make sure that the permissions are correct:', - 'Page_4_Final' => 'Once all this is complete, refresh this page, and you should see the root server login page.', - 'FormatLangNamesLabel' => 'Enter extra languages in format code1:name1 (example "fa:farsi ru:russian"):', - - ); diff --git a/src/legacy/local_server/server_admin/lang/es/name.txt b/src/legacy/local_server/server_admin/lang/es/name.txt deleted file mode 100755 index d236fc3b6..000000000 --- a/src/legacy/local_server/server_admin/lang/es/name.txt +++ /dev/null @@ -1 +0,0 @@ -Español \ No newline at end of file diff --git a/src/legacy/local_server/server_admin/lang/es/server_admin_strings.inc.php b/src/legacy/local_server/server_admin/lang/es/server_admin_strings.inc.php deleted file mode 100755 index 0787e82af..000000000 --- a/src/legacy/local_server/server_admin/lang/es/server_admin_strings.inc.php +++ /dev/null @@ -1,489 +0,0 @@ -. */ - -defined('BMLT_EXEC') or die('Cannot Execute Directly'); // Makes sure that this file is in the correct context. - -$comdef_server_admin_strings = array('server_admin_disclosure' => 'Server Administration', - 'server_admin_naws_spreadsheet_label' => 'Updated World Committee Codes Spreadsheet', - 'update_world_ids_button_text' => 'Update World Committee Codes', - 'update_world_ids_from_spreadsheet_dropdown_text' => 'Update World Committee Codes (Group IDs from NAWS) from NAWS Spreadsheet', - 'server_admin_error_no_world_ids_updated' => 'No World IDs were updated. This could be because your user does not have permission to update the submitted meetings.', - 'server_admin_error_required_spreadsheet_column' => 'Required column does not exist in the spreadsheet: ', - 'server_admin_error_bmlt_id_not_integer' => 'The provided bmlt_id is not an integer: ', - 'server_admin_error_could_not_create_reader' => 'Could not create reader for file: ', - 'server_admin_error_no_files_uploaded' => 'No files were uploaded.', - 'server_admin_error_service_bodies_already_exist' => 'Service bodies with the following World IDs already exist: ', - 'server_admin_error_meetings_already_exist' => 'Meetings with the following World IDs already exist: ', - 'server_admin_ui_num_meetings_updated' => 'Number of meetings updated: ', - 'server_admin_ui_num_meetings_not_updated' => 'Number of meetings that did not need updating: ', - 'server_admin_ui_warning' => 'WARNING', - 'server_admin_ui_errors' => 'Error(s)', - 'server_admin_ui_deleted_meetings_marked' => 'Number of deleted meetings marked so that they won\'t appear in future NAWS exports: ', - 'server_admin_ui_problem_meetings' => 'meetings were found in the spreadsheet that couldn\'t be updated. Problem meeting IDs: ', - 'server_admin_ui_service_bodies_created' => 'Service bodies created: ', - 'server_admin_ui_meetings_created' => 'Meetings created: ', - 'server_admin_ui_users_created' => 'Users created: ', - 'server_admin_ui_refresh_ui_text' => 'Sign out and then sign in again to see the new service bodies, users, and meetings.', - 'import_service_bodies_and_meetings_button_text' => 'Import Service Bodies and Meetings', - 'import_service_bodies_and_meetings_dropdown_text' => 'Import Service Bodies and Meetings from NAWS Export', - 'server_admin_naws_import_spreadsheet_label' => 'NAWS Import Spreadsheet:', - 'server_admin_naws_import_initially_publish' => 'Initialize imported meetings to \'published\': ', - 'server_admin_naws_import_explanation' => 'Uncheck the box to initialize imported meetings to \'unpublished\'. (This is useful if many of the new meetings will need to be edited or deleted, and you don\'t want them showing up in the meantime.)', - 'account_disclosure' => 'Mi cuenta', - 'account_name_label' => 'Nombre de cuenta:', - 'account_login_label' => 'Mi nombre de usuario:', - 'account_type_label' => 'Soy:', - 'account_type_1' => 'Administrador de servidor', - 'account_type_2' => 'Administrador de cuerpo de servicio', - 'ServerMapsURL' => 'https://maps.googleapis.com/maps/api/geocode/xml?address=##SEARCH_STRING##&sensor=false', - 'account_type_4' => 'Pathetic Luser Who Shouldn\'t Even Have Access to This Page -The Author of the Software Pooched it BAD!', - 'account_type_5' => 'Observador de cuerpo de servicio', - 'change_password_label' => 'Cambiar mi contraseña para:', - 'change_password_default_text' => 'Deja eso si usted no desea cambiar su contraseña', - 'account_email_label' => 'Mi dirección de correo electrónico:', - 'email_address_default_text' => 'Introduzca una dirección de correo', - 'account_description_label' => 'Mi descripción:', - 'account_description_default_text' => 'Escriba una descripción', - 'account_change_button_text' => 'Cambiar configuración de mi cuenta', - 'account_change_fader_success_text' => 'La información de la cuenta se cambió con éxito', - 'account_change_fader_failure_text' => 'La información de la cuenta no se ha modificado', - 'meeting_editor_disclosure' => 'Editor de reuniones', - 'meeting_editor_already_editing_confirm' => 'En este momento está editando una nueva reunión. ¿Quieres perder todos los cambios en esa reunión?', - 'meeting_change_fader_success_text' => 'La reunión se cambió con éxito', - 'meeting_change_fader_failure_text' => 'La reunión no se ha modificado', - 'meeting_change_fader_success_delete_text' => 'La reunión se ha eliminado correctamente', - 'meeting_change_fader_fail_delete_text' => 'La reunión no se ha eliminado', - 'meeting_change_fader_success_add_text' => 'La nueva reunión se agregó con exito', - 'meeting_change_fader_fail_add_text' => 'La nueva reunión no fue añadida', - 'meeting_text_input_label' => 'Buscar texto:', - 'access_service_body_label' => 'Tengo acceso a:', - 'meeting_text_input_default_text' => 'Introduzca algun texto de búsqueda', - 'meeting_text_location_label' => 'Se trata de una localidad o código postal', - 'meeting_search_weekdays_label' => 'Búsqueda para los días laborables seleccionados:', - 'meeting_search_weekdays_names' => array('Todos', 'Domingo', 'Lunes', 'Martes', 'Miércoles', 'Jueves', 'Viernes', 'Sábado'), - 'meeting_search_service_bodies_label' => 'Buscar en los cuerpos de servicio seleccionados:', - 'meeting_search_start_time_label' => 'Buscar reuniónes por hora de inicio:', - 'meeting_search_start_time_all_label' => 'Cualquier horario', - 'meeting_search_start_time_morn_label' => 'Por la mañana', - 'meeting_search_start_time_aft_label' => 'Por la tarde', - 'meeting_search_start_time_eve_label' => 'Por la noche', - 'meeting_search_no_results_text' => 'No hay reuniones encontradas', - 'meeting_editor_tab_specifier_text' => 'Buscar por reuniones', - 'meeting_editor_tab_editor_text' => 'Editar reuniones', // TODO: change to 'Edit Or Create Meetings' - 'meeting_editor_create_new_text' => 'Crear una nueva reunión', - 'meeting_editor_location_map_link' => 'Mapa de localización', - 'meeting_editor_screen_match_ll_button' => 'Establezca longitud y la latitud a dirección', - 'meeting_editor_screen_default_text_prompt' => 'Escriba un texto o un número', - 'meeting_is_published' => 'Reunión es publicado', - 'meeting_unpublished_note' => 'Note: Unpublishing a meeting indicates a temporary closure. If this meeting has closed permanently, please delete it.', - 'meeting_editor_screen_meeting_name_label' => 'Nombre de la reunión:', - 'meeting_editor_screen_meeting_name_prompt' => 'Introduzca un nombre de reunión', - 'meeting_editor_screen_meeting_weekday_label' => 'Día de semana:', - 'meeting_editor_screen_meeting_start_label' => 'Hora de inicio de reunion:', - 'meeting_editor_screen_meeting_time_zone_label' => 'Meeting Time Zone:', - 'meeting_editor_screen_meeting_am_label' => 'AM', - 'meeting_editor_screen_meeting_pm_label' => 'PM', - 'meeting_editor_screen_meeting_noon_label' => 'Mediodía', - 'meeting_editor_screen_meeting_midnight_label' => 'Medianoche', - 'meeting_editor_screen_meeting_duration_label' => 'Duración:', - 'meeting_editor_screen_meeting_oe_label' => 'De composición abierta', - 'meeting_editor_screen_meeting_cc_label' => 'Código Comité Mundial:', - 'meeting_editor_screen_meeting_cc_advice' => 'Normally leave this field alone (see documentation).', // TODO: translate - 'meeting_editor_screen_meeting_contact_label' => 'Contacto correo electonico de reunion:', - 'meeting_editor_screen_meeting_contact_prompt' => 'Escriba un correo electrónico de un contacto específico sólo a esta reunión', - 'meeting_editor_screen_meeting_sb_label' => 'Cuerpo de Servicio:', - 'meeting_editor_screen_meeting_sb_default_value' => 'Ningún cuerpo de servicio seleccionado', - 'meeting_editor_screen_meeting_longitude_label' => 'Longitud:', - 'meeting_editor_screen_meeting_longitude_prompt' => 'Escriba una Longitud', - 'meeting_editor_screen_meeting_latitude_label' => 'Latitud:', - 'meeting_editor_screen_meeting_latitude_prompt' => 'Introduzca Un Latitud', - 'meeting_editor_screen_meeting_location_label' => 'Ubicación:', - 'meeting_editor_screen_meeting_location_prompt' => 'Introduzca un Nombre de ubicación (como un nombre del edificio)', - 'meeting_editor_screen_meeting_info_label' => 'Información complementaria:', - 'meeting_editor_screen_meeting_info_prompt' => 'Introduzca cualquier información adicional sobre la ubicación', - 'meeting_editor_screen_meeting_street_label' => 'Dirección:', - 'meeting_editor_screen_meeting_street_prompt' => 'Introduzca una Dirección', - 'meeting_editor_screen_meeting_neighborhood_label' => 'Barrio:', - 'meeting_editor_screen_meeting_neighborhood_prompt' => 'Introduzca un Barrio (No municipio o ciudad subsección)', - 'meeting_editor_screen_meeting_borough_label' => 'Municipio/Ciudad Subsección:', - 'meeting_editor_screen_meeting_borough_prompt' => 'Ingresa una ciudad o ciudad subsección (No Barrio)', - 'meeting_editor_screen_meeting_city_label' => 'Ciudad/Pueblo:', - 'meeting_editor_screen_meeting_city_prompt' => 'Ingresa la ciudad o nombre del pueblo (no condado o municipal)', - 'meeting_editor_screen_meeting_county_label' => 'Condado/Sub-Provincia:', - 'meeting_editor_screen_meeting_county_prompt' => 'Introduzca un condado o nombre Sub-Provincia', - 'meeting_editor_screen_meeting_state_label' => 'Estado/Provincia:', - 'meeting_editor_screen_meeting_state_prompt' => 'Entrar un nombre de estado o provincia', - 'meeting_editor_screen_meeting_zip_label' => 'Código Postal:', - 'meeting_editor_screen_meeting_zip_prompt' => 'Ingrese un Código Postal', - 'meeting_editor_screen_meeting_nation_label' => 'Nación:', - 'meeting_editor_screen_meeting_nation_prompt' => 'Introduzca el nombre de la nación', - 'meeting_editor_screen_meeting_comments_label' => 'Comments:', - 'meeting_editor_screen_meeting_train_lines_label' => 'Train Lines:', - 'meeting_editor_screen_meeting_bus_lines_label' => 'Bus Lines:', - 'meeting_editor_screen_meeting_phone_meeting_number_label' => 'Phone Meeting Dial-in Number:', - 'meeting_editor_screen_meeting_phone_meeting_number_prompt' => 'Enter the dial-in number for a phone or virtual meeting', - 'meeting_editor_screen_meeting_virtual_meeting_link_label' => 'Virtual Meeting Link:', - 'meeting_editor_screen_meeting_virtual_meeting_link_prompt' => 'Enter the link for a virtual meeting', - 'meeting_editor_screen_meeting_virtual_meeting_additional_info_label' => 'Virtual Meeting Additional Information:', - 'meeting_editor_screen_meeting_virtual_meeting_additional_info_prompt' => 'Enter any additional information for joining the virtual meeting, including directly from the app. For example, if the meeting uses Zoom, "Zoom ID: 456 033 8613, Passcode: 1953" would be appropriate.', - 'meeting_editor_screen_meeting_venue_type' => 'Venue Type:', - 'meeting_editor_screen_meeting_venue_type_inperson' => 'In-Person', - 'meeting_editor_screen_meeting_venue_type_virtual' => 'Virtual', - 'meeting_editor_screen_meeting_venue_type_virtualTC' => 'Virtual (temporarily replacing an in-person)', - 'meeting_editor_screen_meeting_venue_type_hybrid' => 'Hybrid (both in-person and virtual)', - 'meeting_editor_screen_meeting_venue_type_validation' => 'You must select a venue type.', - 'meeting_editor_screen_meeting_virtual_info_missing' => 'Virtual or hybrid meetings must have a Virtual Meeting Link, a Phone Meeting Dial-in Number, or Virtual Meeting Additional Information', - 'meeting_editor_screen_meeting_location_warning' => 'Meeting should have a location (at least a city/town and state/province, or a zip/postal code).', - 'meeting_editor_screen_meeting_address_warning' => 'In-person or hybrid meetings should have a street address.', - 'meeting_editor_screen_meeting_url_validation' => 'Virtual Meeting Link is not a valid URL.', - 'meeting_editor_screen_meeting_url_or_phone_warning' => 'Virtual or hybrid meetings should have either a Virtual Meeting Link or a Phone Meeting Dial-in Number', - 'meeting_editor_screen_meeting_additional_warning' => 'Please also fill in Virtual Meeting Additional Information if there is a Virtual Meeting Link.', - 'meeting_editor_screen_in_person_virtual_info_warning' => 'In-person meetings shouldn\'t have any virtual meeting information.', - 'meeting_editor_screen_meeting_virtual_location_info_warning' => 'Virtual meetings shouldn\'t have a location name or address.', - 'meeting_editor_screen_meeting_contact_name_1_label' => 'Contact 1 Name:', - 'meeting_editor_screen_meeting_validation_warning' => 'There are warnings. Are you sure you want to save anyway? If not, press \'cancel\' and go to the Location tab to see the warnings in place and address them.', - 'meeting_editor_screen_meeting_validation_failed' => 'Unable to save due to input errors. Please go to the Location tab to address them, and then retry saving. Errors: ', - 'meeting_editor_screen_meeting_validation_warnings' => 'Input warnings shown on the Location tab: ', - 'meeting_editor_screen_meeting_contact_email_1_label' => 'Contact 1 Email:', - 'meeting_editor_screen_meeting_contact_phone_1_label' => 'Contact 1 Phone:', - 'meeting_editor_screen_meeting_contact_name_2_label' => 'Contact 2 Name:', - 'meeting_editor_screen_meeting_contact_email_2_label' => 'Contact 2 Email:', - 'meeting_editor_screen_meeting_contact_phone_2_label' => 'Contact 2 Phone:', - 'meeting_editor_screen_meeting_publish_search_prompt' => 'Buscar:', - 'meeting_editor_screen_meeting_publish_search_pub' => 'Solo Reuniones Publicado', - 'meeting_editor_screen_meeting_publish_search_unpub' => 'Solo Reuniones inéditas', - 'meeting_editor_screen_meeting_visibility_advice' => 'Esto nunca se muestra en las búsquedas normales de reuniones.', - 'meeting_editor_screen_meeting_publish_search_all' => 'Todas las reuniones', - 'meeting_editor_screen_meeting_create_button' => 'Crear una nueva reunión', - 'meeting_editor_screen_delete_button' => 'Eliminar esta Reunión', - 'meeting_editor_screen_delete_button_confirm' => '¿Está seguro de que desea eliminar esta reunión?', - 'meeting_editor_screen_cancel_button' => 'Cancelar', - 'logout' => 'Salir', - 'meeting_editor_screen_cancel_confirm' => '¿Está seguro de que desea cancelar la edición de este encuentro y perder todos los cambios?', - 'meeting_lookup_failed' => 'La búsqueda de direcciones falló.', - 'meeting_lookup_failed_not_enough_address_info' => 'No hay suficiente información sobre la dirección válida para realizar una búsqueda.', - 'meeting_create_button_name' => 'Salva esto como una nueva reunión', - 'meeting_saved_as_a_copy' => 'Guardar esta reunión como una copia (Crea una nueva reunión)', - 'meeting_save_buttonName' => 'Guarde los cambios a esta reunión', - 'meeting_editor_tab_bar_basic_tab_text' => 'Básico', - 'meeting_editor_tab_bar_location_tab_text' => 'Ubicación', - 'meeting_editor_tab_bar_format_tab_text' => 'Formato', - 'meeting_editor_tab_bar_other_tab_text' => 'Otro', - 'meeting_editor_tab_bar_history_tab_text' => 'Historia', - 'meeting_editor_result_count_format' => '%d Reuniones Encontrados', - 'meeting_id_label' => 'ID de la reunión:', - 'meeting_editor_default_zoom' => '13', - 'meeting_editor_default_weekday' => '2', - 'meeting_editor_default_start_time' => '20:30:00', - 'login_banner' => 'Reuniones básica Listado de herramientas', - 'login_underbanner' => 'Raíz de la consola de administración del servid', - 'login' => 'Nombre de usuario ID', - 'password' => 'Contraseña', - 'button' => 'Acceder', - 'cookie' => 'Debe habilitar las cookies para poder administrar este servidor.', - 'noscript' => 'No se puede administrar este sitio sin JavaScript.', - 'title' => 'Por favor, inicie sesión para administrar el servidor.', - 'edit_Meeting_object_not_found' => 'ERROR: No se encontró la reunión.', - 'edit_Meeting_object_not_changed' => 'ERROR: La reunión no fue cambiada.', - 'edit_Meeting_auth_failure' => 'No tiene permisos para editar esta reunión.', - 'not_auth_1' => 'NO AUTORIZADO', - 'not_auth_2' => 'You are not authorized to administer this server.', - 'not_auth_3' => 'Había un problema con el nombre de usuario o la contraseña que ha introducido.', - 'email_format_bad' => 'La dirección de correo electrónico que has introducido no se ha formateado correctamente.', - 'history_header_format' => '
%spor %s
', - 'history_no_history_available_text' => '

No historia disponible para esta reunión

', - 'service_body_editor_disclosure' => 'Órgano de Administración del Servicio', - 'service_body_change_fader_success_text' => 'El organismo de servicio se cambió con éxito.', - 'service_body_change_fader_fail_text' => 'El cambio del cuerpo de servicio Error.', - 'service_body_editor_screen_sb_id_label' => 'ID:', - 'service_body_editor_screen_sb_name_label' => 'Nombre:', - 'service_body_name_default_prompt_text' => 'Introduzca el nombre de este organismo de servicio', - 'service_body_parent_popup_label' => 'Padres de cuerpo de servicio:', - 'service_body_parent_popup_no_parent_option' => 'Ningún padre (de nivel superior)', - 'service_body_editor_screen_sb_admin_user_label' => 'Administrador Principal:', - 'service_body_editor_screen_sb_admin_description_label' => 'Descripción:', - 'service_body_description_default_prompt_text' => 'Enter A Description of This Service Body', - 'service_body_editor_screen_sb_admin_email_label' => 'Dirección electrónica de contacto:', - 'service_body_email_default_prompt_text' => 'Introduzca una dirección electrónica de contacto para este organismo de servicio', - 'service_body_editor_screen_sb_admin_uri_label' => 'URL del sitio web:', - 'service_body_uri_default_prompt_text' => 'Ingrese una URL del sitio web para este organismo de servicio', - 'service_body_editor_screen_sb_admin_full_editor_label' => 'Editores de reuniones listas completa:', - 'service_body_editor_screen_sb_admin_full_editor_desc' => 'Estos usuarios pueden editar cualquier reuniones dentro este cuerpo de servicio.', - 'service_body_editor_screen_sb_admin_editor_label' => 'Editores de reuniones basico de la lista:', - 'service_body_editor_screen_sb_admin_editor_desc' => 'Estos usuarios pueden editar cualquier Reuniones dentro Este cuerpo de servicio, pero sólo si las reuniones son sin publicar.', - 'service_body_editor_screen_sb_admin_observer_label' => 'Observadores:', - 'service_body_editor_screen_sb_admin_observer_desc' => 'Estos usuarios pueden ver los oculta información (como direcciones de correo electrónico), pero no se puede editar cualquier cosa.', - 'service_body_dirty_confirm_text' => 'Ha realizado cambios a este organismo de servicio. ¿Quieres perder los cambios?', - 'service_body_save_button' => 'Guardar estos cambios al cuerpo de servicio', - 'service_body_create_button' => 'Crear este cuerpo de servicio', - 'service_body_delete_button' => 'Eliminar este cuerpo de servicio', - 'service_body_delete_perm_checkbox' => 'Eliminar este cuerpo de servicio en forma permanente', - 'service_body_delete_button_confirm' => '¿Estas seguro que quieres eliminar este cuerpo de servicio? Make sure that all meetings are either removed or transferred to another service body before performing this function.', - 'service_body_delete_button_confirm_perm' => 'Este cuerpo de servicio será borrada para siempre!', - 'service_body_change_fader_create_success_text' => 'El cuerpo de servicio se creó correctamente', - 'service_body_change_fader_create_fail_text' => 'El Cuerpo de servicios creada no se cumplio', - 'service_body_change_fader_delete_success_text' => 'El cuerpo de servicio se ha eliminado correctamente', - 'service_body_change_fader_delete_fail_text' => 'No se cumplio eliminar el cuerpo de servicio', - 'service_body_change_fader_fail_no_data_text' => 'El cambio del cuerpo de servicio Error, porque no había aportado datos', - 'service_body_change_fader_fail_cant_find_sb_text' => 'El cambio del cuerpo de servicio Error, porque el cuerpo de servicio no se encontró', - 'service_body_change_fader_fail_cant_update_text' => 'The Service Body Change Failed, Because The Service Body Was Not Updated', - 'service_body_change_fader_fail_bad_hierarchy' => 'El cambio del cuerpo de servicio Error, ya que el seleccionado propietario de cuerpo de servicio está bajo este cuerpo de servicio, y no puede ser usad', - 'service_body_cancel_button' => 'Restaurar a original', - 'service_body_editor_type_label' => 'Tipo de cuerpo servicio:', - 'service_body_editor_type_c_comdef_service_body__GRP__' => 'Grupo', - 'service_body_editor_type_c_comdef_service_body__COP__' => 'Co-Op', - 'service_body_editor_type_c_comdef_service_body__ASC__' => 'Comité de Servicio de Área', - 'service_body_editor_type_c_comdef_service_body__RSC__' => 'Conferencia de Servicio Regional', - 'service_body_editor_type_c_comdef_service_body__WSC__' => 'World Service Conference', - 'service_body_editor_type_c_comdef_service_body__MAS__' => 'Metro Area', - 'service_body_editor_type_c_comdef_service_body__ZFM__' => 'Foro Zonal', - 'service_body_editor_type_c_comdef_service_body__GSU__' => 'Group Service Unit', - 'service_body_editor_type_c_comdef_service_body__LSU__' => 'Local Service Unit', - 'service_body_editor_screen_helpline_label' => 'Helpline:', - 'service_body_editor_screen_helpline_prompt' => 'Enter The Helpline Telephone Number', - 'service_body_editor_uri_naws_format_text' => 'Obtener las reuniones de este órgano de servicio como un archivo NAWS-Compatible', - 'edit_Meeting_meeting_id' => 'ID de la reunión:', - 'service_body_editor_create_new_sb_option' => 'Crear un cuerpo nuevo de servicio', - 'service_body_editor_screen_world_cc_label' => 'Código Mundial de Comité:', - 'service_body_editor_screen_world_cc_prompt' => 'Introduzca un código de Comité Mundial', - 'user_editor_disclosure' => 'Administración de usuarios', - 'user_editor_create_new_user_option' => 'Crear un nuevo usuario', - 'user_editor_screen_sb_id_label' => 'ID:', - 'user_editor_account_login_label' => 'Registro de usuarios:', - 'user_editor_login_default_text' => 'Introduzca el nombre de usuario', - 'user_editor_account_type_label' => 'User Is A:', - 'user_editor_user_owner_label' => 'Controlado Por: ', - 'user_editor_account_type_1' => 'Administrador de Servicio', - 'user_editor_account_type_2' => 'Administrador de cuerpo de servicior', - 'user_editor_account_type_3' => 'Editor cuerpo de servicio', - 'user_editor_account_type_5' => 'Observadores de cuerpo de servicio', - 'user_editor_account_type_4' => 'Usario discapacitado', - 'user_editor_account_name_label' => 'Nombre de usuario:', - 'user_editor_name_default_text' => 'Introduzca el nombre de usuario', - 'user_editor_account_description_label' => 'Descripción:', - 'user_editor_description_default_text' => 'Introduzca la descripción del usuario', - 'user_editor_account_email_label' => 'Correo electrónica:', - 'user_editor_email_default_text' => 'Introduzca el user correo electrónico', - 'user_change_fader_success_text' => 'El usuario se cambió con éxito', - 'user_change_fader_fail_text' => 'El cambio de usuario error', - 'user_change_fader_create_success_text' => 'The User Was Successfully Created', - 'user_change_fader_create_fail_text' => 'El usuario crear error', - 'user_change_fader_create_fail_already_exists' => 'Un inicio de sesión del usuario que está intentando crear ya existe.', - 'user_change_fader_delete_success_text' => 'El usuario se ha eliminado correctamente', - 'user_change_fader_delete_fail_text' => 'El usuario borrar error', - 'user_save_button' => 'Guarde los cambios para este usuario', - 'user_create_button' => 'Crear este nuevo usuario', - 'user_cancel_button' => 'Restaurar a original', - 'user_delete_button' => 'Elimine este usuario', - 'user_delete_perm_checkbox' => 'Elimine este usuario forma permanente', - 'user_password_label' => 'Cambiar contraseña para:', - 'user_new_password_label' => 'Establecer contraseña a:', - 'user_password_default_text' => 'Deja eso, a menos que quiera cambiar la contraseña', - 'user_new_password_default_text' => 'Debe introducir una contraseña para un usuario nuevo', - 'user_dirty_confirm_text' => 'Ha realizado cambios a este usuario. ¿Quieres perder los cambios?', - 'user_delete_button_confirm' => '¿Estas seguro que quieres eliminar este usuario?', - 'user_delete_button_confirm_perm' => 'This user will be deleted permanently!', - 'user_create_password_alert_text' => 'Los nuevos usuarios deben tener una contraseña. Usted no ha suministrado una contraseña para este usuario.', - 'user_change_fader_fail_no_data_text' => 'El Cambiar usuario falló, porque no había aportado datos', - 'user_change_fader_fail_cant_find_sb_text' => 'El Cambiar usuario falló, porque el usuario no se encontró', - 'user_change_fader_fail_cant_update_text' => 'El Cambiar usuario falló, porque el usuario no se actualizaba', - 'format_editor_disclosure' => 'Formato de administración', - 'format_change_fader_change_success_text' => 'El formato fue creadó correctamente', - 'format_change_fader_change_fail_text' => 'Error en cambio de formato', - 'format_change_fader_create_success_text' => 'The Format Was Successfully Created', - 'format_change_fader_create_fail_text' => 'Error en crear formato', - 'format_change_fader_delete_success_text' => 'El formato se ha eliminado correctamente', - 'format_change_fader_delete_fail_text' => 'El formato eliminado con error', - 'format_change_fader_fail_no_data_text' => 'El cambio de formato con error, porque no había aportado datos', - 'format_change_fader_fail_cant_find_sb_text' => 'El cambio de formato con error, porque el formato no se encontró', - 'format_change_fader_fail_cant_update_text' => 'El cambio de formato con error, porque el formato no se actualizaba', - 'format_editor_name_default_text' => 'Escriba una descripción muy corta', - 'format_editor_description_default_text' => 'Escriba una descripción más detallada', - 'format_editor_create_format_button_text' => 'Crear nuevo formato', - 'format_editor_cancel_create_format_button_text' => 'Cancelar', - 'format_editor_create_this_format_button_text' => 'Crear este formato', - 'format_editor_change_format_button_text' => 'Cambiar este formato', - 'format_editor_delete_format_button_text' => 'Eliminar este formato', - 'format_editor_reset_format_button_text' => 'Restaurar al original', - 'need_refresh_message_fader_text' => 'Usted debe cargar esta página antes de utilizar esta sección', - 'need_refresh_message_alert_text' => 'Because you have made changes in the Server Administration, Service Body Administration, User Administration, or Format Administration, the information displayed in this section may no longer be accurate, so the page needs to be refreshed. The easiest way to do this, is to Sign Out, then Log In again.', - 'format_editor_delete_button_confirm' => '¿Estas seguro que quieres eliminar este formato?', - 'format_editor_delete_button_confirm_perm' => 'Este formato se eliminará para siempre!', - 'format_editor_missing_key' => 'This format should have an entry for every language (at least a key).', // TODO: translate - 'format_editor_reserved_key' => 'This key is reserved for a venue type format - please use something different.', // TODO: translate - 'min_password_length_string' => 'El contraseña es demasiado corta! Debe ser al menos %d caracteres!', - 'AJAX_Auth_Failure' => 'Error en la autorización para esta operación. Puede haber un problema con la configuración del servidor.', - 'Maps_API_Key_Warning' => 'There is a problem with the Google Maps API Key.', - 'Observer_Link_Text' => 'Meeting Browser', - 'Data_Transfer_Link_Text' => 'Import Meeting Data (WARNING: Replaces Current Data!)', - 'MapsURL' => 'https://maps.google.com/maps?q=##LAT##,##LONG##+(##NAME##)&ll=##LAT##,##LONG##', - 'hidden_value' => 'No se puede mostrar datos-no autorizada', - 'Value_Prompts' => array( - 'id_bigint' => 'ID de reunion', - 'worldid_mixed' => 'World Services ID', - 'service_body' => 'Cuerpo de servicio', - 'service_bodies' => 'Cuerpos de servicio', - 'weekdays' => 'Días de la semana', - 'weekday' => 'Reunión recolecta cada', - 'start_time' => 'Comienza la reunión', - 'duration_time' => 'Reunión Dura', - 'location' => 'Ubicación', - 'duration_time_hour' => 'Hora', - 'duration_time_hours' => 'Horas', - 'duration_time_minute' => 'Minuto', - 'duration_time_minutes' => 'Minutos', - 'lang_enum' => 'Idioma', - 'formats' => 'Formatos', - 'distance' => 'Distancia del Centro', - 'generic' => 'Reunion de NA', - 'close_title' => 'Cierre esta ventana detalle de reuniones', - 'close_text' => 'Cierar ventana', - 'map_alt' => 'Mapa a reunión', - 'map' => 'Sigue este enlace para ver un mapa', - 'title_checkbox_unpub_meeting' => 'Esta reunión es inédito. No puede ser visto por búsquedas regulares.', - 'title_checkbox_copy_meeting' => 'Esta reunión es un duplicado de otra reunión. También es inédito. No puede ser visto por búsquedas regulares.' - ), - 'world_format_codes_prompt' => 'NAWS Format:', - 'world_format_codes' => array( - '' => 'Ninguno', - 'OPEN' => 'Abierto', - 'CLOSED' => 'Cerrado', - 'WCHR' => 'Accesible silla de ruedas', - 'BEG' => 'Principiantes', - 'BT' => 'Texto Basico', - 'CAN' => 'Las Velas', - 'CPT' => '12 Conceptos', - 'CW' => 'Niños son bienvenidos', - 'DISC' => 'Discusión/Participación', - 'GL' => 'Gay/Lesbiana', - 'IP' => 'Estudio IP', - 'IW' => 'Estudio funciona', - 'JFT' => 'Estudio Solo Por Hoy', - 'LC' => 'Vivir Limpios', - 'LIT' => 'Estudio de Literatura', - 'M' => 'Hombres', - 'MED' => 'Meditación', - 'NS' => 'Non-Smoking', - 'QA' => 'Preguntas y Respuestas', - 'RA' => 'Acceso Restringido', - 'S-D' => 'Speaker/Discussion', // TODO translate - 'SMOK' => 'Fumar', - 'SPK' => 'Orador', - 'STEP' => 'Pasos', - 'SWG' => 'Estudio de Guía de Pasos', - 'TOP' => 'Topico', - 'TRAD' => 'Tradicion', - 'VAR' => 'Formato Varía', - 'W' => 'Mujeres', - 'Y' => 'Jovenes', - 'LANG' => 'Idioma alternativo', - 'GP' => 'Guiding Principles', // TODO translate - 'NC' => 'No Children', // TODO translate - 'CH' => 'Closed Holidays', // TODO translate - 'VM' => 'Virtual', // TODO translate - 'HYBR' => 'Virtual and In-Person', // TODO translate - 'TC' => 'Temporarily Closed Facility', // TODO translate - 'SPAD' => 'Spiritual Principle a Day', // TODO translate - ), - 'format_type_prompt' => 'Format Type:', - 'format_type_codes' => array( - '' => 'None', - 'FC1' => 'Meeting Format (Speaker, Book Study, etc.)', - 'FC2' => 'Location Code (Wheelchair Accessible, Limited Parking, etc.)', - 'FC3' => 'Common Needs and Restrictions (Mens Meeting, LGTBQ, No Children, etc.)', - 'O' => 'Attendance by non-addicts (Open, Closed)', - 'LANG' => 'Language', - 'ALERT' => 'Format should be especially prominent (Clean requirement, etc.)', - ), - 'cookie_monster' => 'Este sitio utiliza cookies para almacenar su idioma preferido.', - 'main_prompts' => array( - 'id_bigint' => 'ID', - 'worldid_mixed' => 'World ID', - 'shared_group_id_bigint' => 'Unused', - 'service_body_bigint' => 'Service Body ID', - 'weekday_tinyint' => 'Weekday', - 'venue_type' => 'Venue Type', - 'start_time' => 'Start Time', - 'duration_time' => 'Duration', - 'time_zone' => 'Time Zone', - 'formats' => 'Formats', - 'lang_enum' => 'Language', - 'longitude' => 'Longitude', - 'latitude' => 'Latitude', - 'published' => 'Published', - 'email_contact' => 'Email Contact', - ), - 'check_all' => 'Check All', - 'uncheck_all' => 'Uncheck All', - 'automatically_calculated_on_save' => 'Automatically calculated on save.' -); - -$email_contact_strings = array( - 'meeting_contact_form_subject_format' => "[Contactos de Listado de Reuniones] %s", - 'meeting_contact_message_format' => "%s\n--\nThis message concerns the meeting named \"%s\", which meets at %s, on %s.\nBrowser Link: %s\nEdit Link: %s\nIt was sent directly from the meeting list web server, and the sender is not aware of your email address.\nPlease be aware that replying will expose your email address.\nIf you use \"Reply All\", and there are multiple email recipients, you may expose other people's email addresses.\nPlease respect people's privacy and anonymity; including the original sender of this message." -); - -$change_type_strings = array( - '__THE_MEETING_WAS_CHANGED__' => 'La reunion fue cambiada.', - '__THE_MEETING_WAS_CREATED__' => 'La reunion fue creada.', - '__THE_MEETING_WAS_DELETED__' => 'La reunion fue eliminada.', - '__THE_MEETING_WAS_ROLLED_BACK__' => 'La reunión se ha retrotraído a una versión anterior.', - - '__THE_FORMAT_WAS_CHANGED__' => 'El formato ha cambiado.', - '__THE_FORMAT_WAS_CREATED__' => 'El formato fue creado.', - '__THE_FORMAT_WAS_DELETED__' => 'Formato fue eliminad.', - '__THE_FORMAT_WAS_ROLLED_BACK__' => 'El formato se ha retrotraído a una versión anterior.', - - '__THE_SERVICE_BODY_WAS_CHANGED__' => 'El cuerpo de servicio se ha cambiado.', - '__THE_SERVICE_BODY_WAS_CREATED__' => 'El cuerpo de servicio fue creado.', - '__THE_SERVICE_BODY_WAS_DELETED__' => 'El cuerpo de servicio fue eliminado.', - '__THE_SERVICE_BODY_WAS_ROLLED_BACK__' => 'El cuerpo de servicio se ha retrotraído a una versión anterior.', - - '__THE_USER_WAS_CHANGED__' => 'El usuario ha cambiado.', - '__THE_USER_WAS_CREATED__' => 'Se creó el usuario.', - '__THE_USER_WAS_DELETED__' => 'El usuario se ha eliminado.', - '__THE_USER_WAS_ROLLED_BACK__' => 'El usuario se ha retrotraído a una versión anterior.', - - '__BY__' => 'por', - '__FOR__' => 'para' -); - -$detailed_change_strings = array( - 'was_changed_from' => 'fue cambiado de', - 'to' => 'a', - 'was_changed' => 'cambiado', - 'was_added_as' => 'fue introducido como', - 'was_deleted' => 'fue elimanado', - 'was_published' => 'La reunión se publicó', - 'was_unpublished' => 'El reunión fue inédito', - 'formats_prompt' => 'Formato de reunion', - 'duration_time' => 'La duración de reunión', - 'start_time' => 'Hora de inicio de la reunion', - 'longitude' => 'La longitud de reunión', - 'latitude' => 'El latitud de reunión', - 'sb_prompt' => 'La reunión cambió su cuerpo de servicio de', - 'id_bigint' => 'ID de la reunion', - 'lang_enum' => 'Idioma de la reunion', - 'worldid_mixed' => 'El ID de grupo compartida', // TODO: translate The World Committee Code - 'weekday_tinyint' => 'El día de la semana en que se reúne la reunión', - 'non_existent_service_body' => 'Cuerpo de Servicio ya no existe', -); - -defined('_END_CHANGE_REPORT') or define('_END_CHANGE_REPORT', '.'); diff --git a/src/legacy/local_server/server_admin/lang/fa/data_transfer_strings.php b/src/legacy/local_server/server_admin/lang/fa/data_transfer_strings.php deleted file mode 100755 index 1ebd15a51..000000000 --- a/src/legacy/local_server/server_admin/lang/fa/data_transfer_strings.php +++ /dev/null @@ -1,45 +0,0 @@ -.*/ - defined('BMLT_EXEC') or die('Cannot Execute Directly'); // Makes sure that this file is in the correct context. - - $comdef_data_transfer_strings = array ( 'key_strings' => array ( 'id_bigint' => 1, - 'worldid_mixed' => 1, - 'shared_group_id_bigint' => 1, - 'service_body_bigint' => 1, - 'weekday_tinyint' => 1, - 'start_time' => 1, - 'duration_time' => 1, - 'formats' => 1, - 'lang_enum' => 1, - 'longitude' => 1, - 'latitude' => 1, - 'published' => 1, - 'email_contact' => 1 - ), - - 'days' => array ( 'Sunday', - 'Monday', - 'Tuesday', - 'Wednesday', - 'Thursday', - 'Friday', - 'Saturday' - ), - ); diff --git a/src/legacy/local_server/server_admin/lang/fa/install_wizard_strings.php b/src/legacy/local_server/server_admin/lang/fa/install_wizard_strings.php deleted file mode 100755 index 8ca9805bd..000000000 --- a/src/legacy/local_server/server_admin/lang/fa/install_wizard_strings.php +++ /dev/null @@ -1,165 +0,0 @@ -.*/ - defined('BMLT_EXEC') or die('Cannot Execute Directly'); // Makes sure that this file is in the correct context. - - global $comdef_install_wizard_strings; - - $comdef_install_wizard_strings = array ( - 'Database_Version_Error' => 'ERROR: You must have PHP Version 5.6 or greater installed on this server!', - 'Database_PDO_Error' => 'ERROR: You do not have PHP PDO installed!', - 'Database_Type_Error' => 'ERROR: Even though you have PDO, you have no database drivers installed!', - 'Database_Type_MySQL_Error' => 'ERROR: Even though you have PDO and you have database drivers installed, none of the are MySQL (the only supported driver)!', - 'Database_TestButton_Text' => 'TEST', - 'Database_TestButton_Success' => 'The database connection was successful.', - 'Database_TestButton_Fail' => 'The database connection failed: ', - 'Database_TestButton_Fail2' => 'The database connection failed because there is already an initialized database.', - 'Database_Whitespace_Note' => 'Warning: %s has whitespace at the beginning or end.', - - 'AJAX_Handler_DB_Connect_Error' => 'The database connection failed! Please make sure that the database exists, IS COMPLETELY EMPTY, the user is created, and that user has full permissions on the empty database.', - 'AJAX_Handler_DB_Established_Error' => 'The database already exists, and has been set up! You cannot use this setup to overwrite an existing database!', - 'AJAX_Handler_DB_Incomplete_Error' => 'There is not enough information to initialize the database!', - - 'NoDatabase_Note_AlreadySet' => 'The database has already been initialized with the provided table prefix. Please choose a new one.', - 'NoDatabase_Note_GenericError' => 'There is an error connecting to the database. Please check your database settings.', - 'NoDatabase_Note_ClickHere' => 'Click here to go back to the database set up page.', - 'NoDatabase_Note_PasswordIssue' => 'You must choose a username and password for the Server Administrator user.', - 'NoDatabase_Note_ServerSettings_ClickHere' => 'Click here to go back to the server settings page.', - 'NoServerAdmin_Note_AlreadySet' => 'There is already an existing database, so you cannot set up a Server Administrator account (One already exists).', - 'NeedLongerPasswordNote' => 'This password is too short. It must be at least %d characters long.', - - 'Prev_Button' => 'PREVIOUS', - 'Next_Button' => 'NEXT', - - 'Page_1_Tab' => 'STEP 1: Database', - 'Page_1_Heading' => 'Database Connection Settings', - 'Page_1_Text' => 'Before you can apply the settings on this page, you must set up a new COMPLETELY EMPTY database, and create a database user that has full user rights on that database.', - - 'Database_Name' => 'Database Name:', - 'Database_Name_Default_Text' => 'Enter A Database Name', - 'Database_Type' => 'Database Type:', - 'Database_Host' => 'Database Host:', - 'Database_Host_Default_Text' => 'Enter A Database Host', - 'Database_Host_Additional_Text' => 'This is usually "localhost."', - 'Table_Prefix' => 'Table Prefix:', - 'Table_Prefix_Default_Text' => 'Enter A Table Prefix', - 'Table_Prefix_Additional_Text' => 'Only for multiple root servers sharing a database.', - 'Database_User' => 'Database User:', - 'Database_User_Default_Text' => 'Enter A Database User Name', - 'Database_PW' => 'Database Password:', - 'Database_PW_Default_Text' => 'Enter A Database Password', - 'Database_PW_Additional_Text' => 'Make this an ugly, difficult password. It has a great deal of power, and you will never need to remember it.', - - 'Maps_API_Key_Warning' => 'There is a problem with the Google Maps API Key.', - 'Maps_API_Key_Not_Set' => 'The Google Maps API key is not set.', - 'Maps_API_Key_Valid' => 'Google Maps API Key is valid.', - 'Maps_API_Key_ClickHere' => 'Click here to go back to the Google Maps API Key set up page.', - - 'Page_2_Tab' => 'STEP 2: Google Maps API Settings', - 'Page_2_Heading' => 'Google Maps API Settings', - 'Page_2_API_Key_Prompt' => 'Enter the Google API Key for Geocoding:', - 'Page_2_API_Key_Set_Button' => 'TEST KEY', - 'Page_2_API_Key_Not_Set_Prompt' => 'SET API KEY FIRST', - 'Page_2_Text' => 'When saving a meeting, the BMLT Root Server uses the Google Maps API to determine the latitude and longitude for the meeting address. These settings are required to allow the BMLT Root Server to communicate with the Google Maps API.', - - 'Page_3_Tab' => 'STEP 3: Server Settings', - 'Page_3_Heading' => 'Set Various Global Server Settings', - 'Page_3_Text' => 'These are a few settings that affect the administration and general configuration of this server. Most server settings are done in the server itself.', - 'Admin_Login' => 'Server Administrator Login:', - 'Admin_Login_Default_Text' => 'Enter A Server Administrator Login', - 'Admin_Login_Additional_Text' => 'This is the login string for the Server Administrator.', - 'Admin_Password' => 'Server Administrator Password:', - 'Admin_Password_Default_Text' => 'Enter A Server Administrator Password', - 'Admin_Password_Additional_Text' => 'Make sure that this is a non-trivial password! It has a great deal of power! (Also, don\'t forget it).', - 'ServerAdminName' => 'Server Administrator', - 'ServerAdminDesc' => 'Main Server Administrator', - 'ServerLangLabel' => 'Default Server Language:', - 'DistanceUnitsLabel' => 'Distance Units:', - 'DistanceUnitsMiles' => 'Miles', - 'DistanceUnitsKM' => 'Kilometres', - 'SearchDepthLabel' => 'Density of Meetings For Automatic Search:', - 'SearchDepthText' => 'This is an approximation of how many meetings need to be found in the automatic radius selection. More meetings means a bigger radius.', - 'HistoryDepthLabel' => 'How Many Meeting Changes To Save:', - 'HistoryDepthText' => ' The longer the history, the larger the database will become.', - 'TitleTextLabel' => 'The Title Of The Administration Screen:', - 'TitleTextDefaultText' => 'Enter A Short Title For the Editing Login Page', - 'BannerTextLabel' => 'Prompt For Administration Login:', - 'BannerTextDefaultText' => 'Enter A Short Prompt For The Login Page', - 'RegionBiasLabel' => 'Region Bias:', - 'PasswordLengthLabel' => 'Minimum Password Length:', - 'PasswordLengthExtraText' => 'This will also affect the Server Administrator password, above.', - 'DefaultClosedStatus' => 'Meetings Are Considerd "CLOSED" by Default:', - 'DefaultClosedStatusExtraText' => 'This primarily affects the export to NAWS.', - 'DurationLabel' => 'Default Meeting Duration:', - 'DurationHourLabel' => 'Hours', - 'DurationMinutesLabel' => 'Minutes', - 'LanguageSelectorEnableLabel' => 'Display Language Selector On Login:', - 'LanguageSelectorEnableExtraText' => 'If you select this, a popup menu will appear in the login screen, so administrators can select their language.', - 'SemanticAdminLabel' => 'Enable Semantic Administration:', - 'SemanticAdminExtraText' => 'If not checked, then all administration must be done via the Root Server login (No apps).', - 'EmailContactEnableLabel' => 'Allow Email Contacts From Meetings:', - 'EmailContactEnableExtraText' => 'If you select this, site visitors will be able to send emails from meeting records.', - 'EmailContactAdminEnableLabel' => 'Include Service Body Administrator On These Emails:', - 'EmailContactAdminEnableExtraText' => 'Sends copies of these emails to the Service Body Administrator (if they are not the primary recipient).', - 'EmailContactAllAdminEnableLabel' => 'Include All Service Body Administrators On These Emails:', - 'EmailContactAllAdminEnableExtraText' => 'Sends copies of these emails to all of the relevant Service Body Administrators.', - - 'Page_4_Initialize_Root_Server_Heading' => 'Initialize the Root Server', - 'Page_4_Initialize_Root_Server_Text' => 'The button below will initialize the Root Server with an empty database and a Server Administrator user.', - 'Page_4_Initialize_Root_Server_Button' => 'Initialize Root Server', - - 'Page_4_Tab' => 'STEP 4: Save The Settings', - 'Page_4_Heading' => 'Create the Settings File', - 'Page_4_Text' => 'The root server was unable to create the settings file for you. Instead, we ask you to create it yourself, via FTP or a control panel file manager, name it "auto-config.inc.php", and paste the following text into the file:', - - 'NAWS_Export_Spreadsheet_Optional' => 'NAWS Export Spreadsheet (Optional): ', - 'NAWS_Export_Spreadsheet_Initially_Publish' => 'Initialize imported meetings to \'published\': ', - - 'DefaultPasswordLength' => 10, - 'DefaultMeetingCount' => 10, - 'DefaultChangeDepth' => 5, - 'DefaultDistanceUnits' => 'mi', - 'DefaultDurationTime' => '01:30:00', - 'DurationTextInitialText' => 'N.A. Meetings are usually 90 minutes long (an hour and a half), unless otherwise indicated.', - 'time_format' => 'g:i A', - 'change_date_format' => 'g:i A, n/j/Y', - 'BannerTextInitialText' => 'Administration Login', - 'TitleTextInitialText' => 'Basic Meeting List Toolbox Administration', - 'DefaultRegionBias' => 'us', - 'search_spec_map_center' => array ( 'longitude' => -118.563659, 'latitude' => 34.235918, 'zoom' => 6 ), - 'DistanceChoices' => array ( 2, 5, 10, 20, 50 ), - 'HistoryChoices' => array ( 1, 2, 3, 5, 8, 10, 15 ), - 'PW_LengthChices' => array ( 6, 8, 10, 12, 16 ), - 'ServerAdminDefaultLogin' => 'serveradmin', - - 'Explanatory_Text_1_Initial_Intro' => 'This install wizard will guide you through the process of creating an initial database, as well as a configuration file. In the final step, we will create a settings file, and initialize an empty database.', - 'Explanatory_Text_1_DB_Intro' => 'The first thing that you need to do, is create a new, EMPTY database, and a database user that has full access to that database. This is usually done via your Web site Control Panel. Once you have created the database, you need to enter the information about that database into the text items on this page.', - - 'Explanatory_Text_2_Region_Bias_Intro' => 'The "Region Bias" is a code that is sent to Google when a location search is done, and can help Google to make sense of ambiguous search queries.', - 'Explanatory_Text_2_API_key_Intro' => 'The "API Key" is a key that you need to register with Google in order to be able to use their mapping service.', - 'Explanatory_Text_2_API_key_2_Intro' => 'You will need to provide a valid API Key in order to create new meetings in the Root Server.', - - 'Explanatory_Text_3_Server_Admin_Intro' => 'The Server Administrator is the main user for the server. It is the only account that can create new users and Service bodies, and is very powerful. You should create a login ID and a non-trivial password for this account. You\'ll be able to modify the other aspects of the account on the main server, once the database has been set up.', - 'Explanatory_Text_3_Misc_Intro' => 'These are various settings that affect how the root server behaves and appears.', - - 'Explanatory_Text_4_Main_Intro' => 'If you have entered the database information, provided a valid Google Maps API Key, and specified the login information for the Server Administrator, then you can initialize the root server here. Remember that the database must be COMPLETELY EMPTY of BMLT Root Server tables for this server (It can have tables for other servers or services).', - 'Explanatory_Text_4_NAWS_Export' => 'Optionally, you can import the meetings from a NAWS export spreadsheet. Uncheck the box to initialize them to \'unpublished\'. (This is useful if many of the new meetings will need to be edited or deleted, and you don\'t want them showing up in the meantime.)', - 'Explanatory_Text_4_File_Intro' => 'The text in the box below is the PHP source code for the main settings file. You will need to create a file on the server with this text in it. The file is at the same level as the main server directory for the root server.', - 'Explanatory_Text_4_File_Extra' => 'You also need to make sure that the file permissions are restricted (chmod 0644). This prevents the file from being written, and the root server will not run unless the file has the correct permissions.', - 'Page_4_PathInfo' => 'The file needs to be placed as %s/auto-config.inc.php, which is where your %s directory is. After the file has been created and you have put the above text into it, you should execute the following command to make sure that the permissions are correct:', - 'Page_4_Final' => 'Once all this is complete, refresh this page, and you should see the root server login page.', - 'FormatLangNamesLabel' => 'Enter extra languages in format code1:name1 (example "fa:farsi ru:russian"):', - ); diff --git a/src/legacy/local_server/server_admin/lang/fa/name.txt b/src/legacy/local_server/server_admin/lang/fa/name.txt deleted file mode 100755 index 159b8f2e4..000000000 --- a/src/legacy/local_server/server_admin/lang/fa/name.txt +++ /dev/null @@ -1 +0,0 @@ -فارسی \ No newline at end of file diff --git a/src/legacy/local_server/server_admin/lang/fa/server_admin_strings.inc.php b/src/legacy/local_server/server_admin/lang/fa/server_admin_strings.inc.php deleted file mode 100755 index af3fc46df..000000000 --- a/src/legacy/local_server/server_admin/lang/fa/server_admin_strings.inc.php +++ /dev/null @@ -1,491 +0,0 @@ -. */ - -defined('BMLT_EXEC') or die('Cannot Execute Directly'); // Makes sure that this file is in the correct context. - -$comdef_server_admin_strings = array('server_admin_disclosure' => 'Server Administration', - 'server_admin_naws_spreadsheet_label' => 'Updated World Committee Codes Spreadsheet', - 'update_world_ids_button_text' => 'Update World Committee Codes', - 'update_world_ids_from_spreadsheet_dropdown_text' => 'Update World Committee Codes (Group IDs from NAWS) from NAWS Spreadsheet', - 'server_admin_error_no_world_ids_updated' => 'No World IDs were updated. This could be because your user does not have permission to update the submitted meetings.', - 'server_admin_error_required_spreadsheet_column' => 'Required column does not exist in the spreadsheet: ', - 'server_admin_error_bmlt_id_not_integer' => 'The provided bmlt_id is not an integer: ', - 'server_admin_error_could_not_create_reader' => 'Could not create reader for file: ', - 'server_admin_error_no_files_uploaded' => 'No files were uploaded.', - 'server_admin_error_service_bodies_already_exist' => 'Service bodies with the following World IDs already exist: ', - 'server_admin_error_meetings_already_exist' => 'Meetings with the following World IDs already exist: ', - 'server_admin_ui_num_meetings_updated' => 'Number of meetings updated: ', - 'server_admin_ui_num_meetings_not_updated' => 'Number of meetings that did not need updating: ', - 'server_admin_ui_warning' => 'WARNING', - 'server_admin_ui_errors' => 'Error(s)', - 'server_admin_ui_deleted_meetings_marked' => 'Number of deleted meetings marked so that they won\'t appear in future NAWS exports: ', - 'server_admin_ui_problem_meetings' => 'meetings were found in the spreadsheet that couldn\'t be updated. Problem meeting IDs: ', - 'server_admin_ui_service_bodies_created' => 'Service bodies created: ', - 'server_admin_ui_meetings_created' => 'Meetings created: ', - 'server_admin_ui_users_created' => 'Users created: ', - 'server_admin_ui_refresh_ui_text' => 'Sign out and then sign in again to see the new service bodies, users, and meetings.', - 'import_service_bodies_and_meetings_button_text' => 'Import Service Bodies and Meetings', - 'import_service_bodies_and_meetings_dropdown_text' => 'Import Service Bodies and Meetings from NAWS Export', - 'server_admin_naws_import_spreadsheet_label' => 'NAWS Import Spreadsheet:', - 'server_admin_naws_import_initially_publish' => 'Initialize imported meetings to \'published\': ', - 'server_admin_naws_import_explanation' => 'Uncheck the box to initialize imported meetings to \'unpublished\'. (This is useful if many of the new meetings will need to be edited or deleted, and you don\'t want them showing up in the meantime.)', - 'account_disclosure' => 'My Account', - 'account_name_label' => 'My Account Name:', - 'account_login_label' => 'My Login:', - 'account_type_label' => 'I Am A:', - 'account_type_1' => 'Server Administrator', - 'account_type_2' => 'Service Body Administrator', - 'ServerMapsURL' => 'https://maps.googleapis.com/maps/api/geocode/xml?address=##SEARCH_STRING##&sensor=false', - 'account_type_4' => 'Pathetic Luser Who Shouldn\'t Even Have Access to This Page -The Author of the Software Pooched it BAD!', - 'account_type_5' => 'Service Body Observer', - 'change_password_label' => 'Change My Password To:', - 'change_password_default_text' => 'Leave This Alone If You Don\'t Want To Change Your Password', - 'account_email_label' => 'My Email Address:', - 'email_address_default_text' => 'Enter An Email Address', - 'account_description_label' => 'My Description:', - 'account_description_default_text' => 'Enter A Description', - 'account_change_button_text' => 'Change My Account Settings', - 'account_change_fader_success_text' => 'The Account Information Was Successfully Changed', - 'account_change_fader_failure_text' => 'The Account Information Was Not Changed', - 'meeting_editor_disclosure' => 'Meeting Editor', - 'meeting_editor_already_editing_confirm' => 'You are currently editing another meeting. Do you want to lose all changes in that meeting?', - 'meeting_change_fader_success_text' => 'The Meeting Was Successfully Changed', - 'meeting_change_fader_failure_text' => 'The Meeting Was Not Changed', - 'meeting_change_fader_success_delete_text' => 'The Meeting Was Successfully Deleted', - 'meeting_change_fader_fail_delete_text' => 'The Meeting Was Not Deleted', - 'meeting_change_fader_success_add_text' => 'The New Meeting Was Successfully Added', - 'meeting_change_fader_fail_add_text' => 'The New Meeting Was Not Added', - 'meeting_text_input_label' => 'Search For Text:', - 'access_service_body_label' => 'I Have Access to:', - 'meeting_text_input_default_text' => 'Enter Some Search Text', - 'meeting_text_location_label' => 'This is a Location or PostCode', - 'meeting_search_weekdays_label' => 'Search For Selected Weekdays:', - 'meeting_search_weekdays_names' => array('All', 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'), - 'meeting_search_service_bodies_label' => 'Search In Selected Service Bodies:', - 'meeting_search_start_time_label' => 'Search By Meeting Start Time:', - 'meeting_search_start_time_all_label' => 'Any Time', - 'meeting_search_start_time_morn_label' => 'Morning', - 'meeting_search_start_time_aft_label' => 'Afternoon', - 'meeting_search_start_time_eve_label' => 'Evening', - 'meeting_search_no_results_text' => 'No Meetings Found', - 'meeting_editor_tab_specifier_text' => 'Search For Meetings', - 'meeting_editor_tab_editor_text' => 'Edit Or Create Meetings', - 'meeting_editor_create_new_text' => 'Create A New Meeting', - 'meeting_editor_location_map_link' => 'Location Map', - 'meeting_editor_screen_match_ll_button' => 'Set Longitude and Latitude to Address', - 'meeting_editor_screen_default_text_prompt' => 'Enter Some Text or a Number', - 'meeting_is_published' => 'Meeting is Published', - 'meeting_unpublished_note' => 'Note: Unpublishing a meeting indicates a temporary closure. If this meeting has closed permanently, please delete it.', - 'meeting_editor_screen_meeting_name_label' => 'Meeting Name:', - 'meeting_editor_screen_meeting_name_prompt' => 'Enter A Meeting Name', - 'meeting_editor_screen_meeting_weekday_label' => 'Weekday:', - 'meeting_editor_screen_meeting_start_label' => 'Meeting Start Time:', - 'meeting_editor_screen_meeting_time_zone_label' => 'Meeting Time Zone:', - 'meeting_editor_screen_meeting_am_label' => 'AM', - 'meeting_editor_screen_meeting_pm_label' => 'PM', - 'meeting_editor_screen_meeting_noon_label' => 'Noon', - 'meeting_editor_screen_meeting_midnight_label' => 'Midnight', - 'meeting_editor_screen_meeting_duration_label' => 'Duration:', - 'meeting_editor_screen_meeting_oe_label' => 'Open-Ended', - 'meeting_editor_screen_meeting_cc_label' => 'World Committee Code:', - 'meeting_editor_screen_meeting_cc_advice' => 'Normally leave this field alone (see documentation).', // TODO: translate - 'meeting_editor_screen_meeting_contact_label' => 'Meeting Email Contact:', - 'meeting_editor_screen_meeting_contact_prompt' => 'Enter An Email for A Contact Specific Only to This Meeting', - 'meeting_editor_screen_meeting_sb_label' => 'Service Body:', - 'meeting_editor_screen_meeting_sb_default_value' => 'No Service Body Selected', - 'meeting_editor_screen_meeting_longitude_label' => 'Longitude:', - 'meeting_editor_screen_meeting_longitude_prompt' => 'Enter A Longitude', - 'meeting_editor_screen_meeting_latitude_label' => 'Latitude:', - 'meeting_editor_screen_meeting_latitude_prompt' => 'Enter A Latitude', - 'meeting_editor_screen_meeting_location_label' => 'Location:', - 'meeting_editor_screen_meeting_location_prompt' => 'Enter A Location Name (Like a Building Name)', - 'meeting_editor_screen_meeting_info_label' => 'Extra Info:', - 'meeting_editor_screen_meeting_info_prompt' => 'Enter Any Additional Location Information', - 'meeting_editor_screen_meeting_street_label' => 'Street Address:', - 'meeting_editor_screen_meeting_street_prompt' => 'Enter A Street Address', - 'meeting_editor_screen_meeting_neighborhood_label' => 'Neighborhood:', - 'meeting_editor_screen_meeting_neighborhood_prompt' => 'Enter A Neighborhood (Not Borough or City Subsection)', - 'meeting_editor_screen_meeting_borough_label' => 'Borough/City Subsection:', - 'meeting_editor_screen_meeting_borough_prompt' => 'Enter A Borough or City Subsection (Not Neighborhood)', - 'meeting_editor_screen_meeting_city_label' => 'City/Town:', - 'meeting_editor_screen_meeting_city_prompt' => 'Enter A City or Town Name (Not County or Borough)', - 'meeting_editor_screen_meeting_county_label' => 'County/Sub-Province:', - 'meeting_editor_screen_meeting_county_prompt' => 'Enter A County or Sub-Province Name', - 'meeting_editor_screen_meeting_state_label' => 'State/Province:', - 'meeting_editor_screen_meeting_state_prompt' => 'Enter A State or Province Name', - 'meeting_editor_screen_meeting_zip_label' => 'Zip Code/Postal Code:', - 'meeting_editor_screen_meeting_zip_prompt' => 'Enter A Postal Code', - 'meeting_editor_screen_meeting_nation_label' => 'Nation:', - 'meeting_editor_screen_meeting_nation_prompt' => 'Enter The Nation Name', - 'meeting_editor_screen_meeting_comments_label' => 'Comments:', - 'meeting_editor_screen_meeting_train_lines_label' => 'Train Lines:', - 'meeting_editor_screen_meeting_bus_lines_label' => 'Bus Lines:', - 'meeting_editor_screen_meeting_phone_meeting_number_label' => 'Phone Meeting Dial-in Number:', - 'meeting_editor_screen_meeting_phone_meeting_number_prompt' => 'Enter the dial-in number for a phone or virtual meeting', - 'meeting_editor_screen_meeting_virtual_meeting_link_label' => 'Virtual Meeting Link:', - 'meeting_editor_screen_meeting_virtual_meeting_link_prompt' => 'Enter the link for a virtual meeting', - 'meeting_editor_screen_meeting_virtual_meeting_additional_info_label' => 'Virtual Meeting Additional Information:', - 'meeting_editor_screen_meeting_virtual_meeting_additional_info_prompt' => 'Enter any additional information for joining the virtual meeting, including directly from the app. For example, if the meeting uses Zoom, "Zoom ID: 456 033 8613, Passcode: 1953" would be appropriate.', - 'meeting_editor_screen_meeting_venue_type' => 'Venue Type:', - 'meeting_editor_screen_meeting_venue_type_inperson' => 'In-Person', - 'meeting_editor_screen_meeting_venue_type_virtual' => 'Virtual', - 'meeting_editor_screen_meeting_venue_type_virtualTC' => 'Virtual (temporarily replacing an in-person)', - 'meeting_editor_screen_meeting_venue_type_hybrid' => 'Hybrid (both in-person and virtual)', - 'meeting_editor_screen_meeting_venue_type_validation' => 'You must select a venue type.', - 'meeting_editor_screen_meeting_virtual_info_missing' => 'Virtual or hybrid meetings must have a Virtual Meeting Link, a Phone Meeting Dial-in Number, or Virtual Meeting Additional Information', - 'meeting_editor_screen_meeting_location_warning' => 'Meeting should have a location (at least a city/town and state/province, or a zip/postal code).', - 'meeting_editor_screen_meeting_address_warning' => 'In-person or hybrid meetings should have a street address.', - 'meeting_editor_screen_meeting_url_validation' => 'Virtual Meeting Link is not a valid URL.', - 'meeting_editor_screen_meeting_url_or_phone_warning' => 'Virtual or hybrid meetings should have either a Virtual Meeting Link or a Phone Meeting Dial-in Number', - 'meeting_editor_screen_meeting_additional_warning' => 'Please also fill in Virtual Meeting Additional Information if there is a Virtual Meeting Link.', - 'meeting_editor_screen_in_person_virtual_info_warning' => 'In-person meetings shouldn\'t have any virtual meeting information.', - 'meeting_editor_screen_meeting_virtual_location_info_warning' => 'Virtual meetings shouldn\'t have a location name or address.', - 'meeting_editor_screen_meeting_validation_warning' => 'There are warnings. Are you sure you want to save anyway? If not, press \'cancel\' and go to the Location tab to see the warnings in place and address them.', - 'meeting_editor_screen_meeting_validation_failed' => 'Unable to save due to input errors. Please go to the Location tab to address them, and then retry saving. Errors: ', - 'meeting_editor_screen_meeting_validation_warnings' => 'Input warnings shown on the Location tab: ', - 'meeting_editor_screen_meeting_contact_name_1_label' => 'Contact 1 Name:', - 'meeting_editor_screen_meeting_contact_email_1_label' => 'Contact 1 Email:', - 'meeting_editor_screen_meeting_contact_phone_1_label' => 'Contact 1 Phone:', - 'meeting_editor_screen_meeting_contact_name_2_label' => 'Contact 2 Name:', - 'meeting_editor_screen_meeting_contact_email_2_label' => 'Contact 2 Email:', - 'meeting_editor_screen_meeting_contact_phone_2_label' => 'Contact 2 Phone:', - 'meeting_editor_screen_meeting_publish_search_prompt' => 'Look For:', - 'meeting_editor_screen_meeting_publish_search_pub' => 'Published Meetings Only', - 'meeting_editor_screen_meeting_publish_search_unpub' => 'Unpublished Meetings Only', - 'meeting_editor_screen_meeting_visibility_advice' => 'This is never displayed in normal meeting searches.', - 'meeting_editor_screen_meeting_publish_search_all' => 'All Meetings', - 'meeting_editor_screen_meeting_create_button' => 'Create A New Meeting', - 'meeting_editor_screen_delete_button' => 'Delete This Meeting', - 'meeting_editor_screen_delete_button_confirm' => 'Are you sure that you want to delete this meeting?', - 'meeting_editor_screen_cancel_button' => 'Cancel', - 'logout' => 'Sign Out', - 'meeting_editor_screen_cancel_confirm' => 'Are you sure that you want to cancel editing this meeting, and lose all changes?', - 'meeting_lookup_failed' => 'The address lookup failed.', - 'meeting_lookup_failed_not_enough_address_info' => 'There is not enough valid address information to do a lookup.', - 'meeting_create_button_name' => 'Save This As A New Meeting', - 'meeting_saved_as_a_copy' => 'Save This Meeting As A Copy (Creates A New Meeting)', - 'meeting_save_buttonName' => 'Save the Changes to This Meeting', - 'meeting_editor_tab_bar_basic_tab_text' => 'Basic', - 'meeting_editor_tab_bar_location_tab_text' => 'Location', - 'meeting_editor_tab_bar_format_tab_text' => 'Format', - 'meeting_editor_tab_bar_other_tab_text' => 'Other', - 'meeting_editor_tab_bar_history_tab_text' => 'History', - 'meeting_editor_result_count_format' => '%d Meetings Found', - 'meeting_id_label' => 'Meeting ID:', - 'meeting_editor_default_zoom' => '13', - 'meeting_editor_default_weekday' => '2', - 'meeting_editor_default_start_time' => '20:30:00', - 'login_banner' => 'Basic Meeting List Toolbox', - 'login_underbanner' => 'Root Server Administration Console', - 'login' => 'Login ID', - 'password' => 'Password', - 'button' => 'Log In', - 'cookie' => 'You must enable cookies in order to administer this server.', - 'noscript' => 'You cannot administer this site without JavaScript.', - 'title' => 'Please log in to administer the server.', - 'edit_Meeting_object_not_found' => 'ERROR: The meeting was not found.', - 'edit_Meeting_object_not_changed' => 'ERROR: The meeting was not changed.', - 'edit_Meeting_auth_failure' => 'You are not authorized to edit this meeting.', - 'not_auth_1' => 'NOT AUTHORIZED', - 'not_auth_2' => 'You are not authorized to administer this server.', - 'not_auth_3' => 'There was a problem with the user name or password that you entered.', - 'email_format_bad' => 'The email address that you entered was not formatted correctly.', - 'history_header_format' => '
%sby %s
', - 'history_no_history_available_text' => '

No History Available For This Meeting

', - 'service_body_editor_disclosure' => 'Service Body Administration', - 'service_body_change_fader_success_text' => 'The Service Body Was Successfully Changed', - 'service_body_change_fader_fail_text' => 'The Service Body Change Failed', - 'service_body_editor_screen_sb_id_label' => 'ID:', - 'service_body_editor_screen_sb_name_label' => 'Name:', - 'service_body_name_default_prompt_text' => 'Enter the Name of This Service Body', - 'service_body_parent_popup_label' => 'Service Body Parent:', - 'service_body_parent_popup_no_parent_option' => 'No Parent (Top-Level)', - 'service_body_editor_screen_sb_admin_user_label' => 'Primary Admin:', - 'service_body_editor_screen_sb_admin_description_label' => 'Description:', - 'service_body_description_default_prompt_text' => 'Enter A Description of This Service Body', - 'service_body_editor_screen_sb_admin_email_label' => 'Contact Email:', - 'service_body_email_default_prompt_text' => 'Enter A Contact Email Address for This Service Body', - 'service_body_editor_screen_sb_admin_uri_label' => 'Web Site URL:', - 'service_body_uri_default_prompt_text' => 'Enter A Web Site URL for This Service Body', - 'service_body_editor_screen_sb_admin_full_editor_label' => 'Full Meeting List Editors:', - 'service_body_editor_screen_sb_admin_full_editor_desc' => 'These Users Can Edit Any Meetings In This Service Body.', - 'service_body_editor_screen_sb_admin_editor_label' => 'Basic Meeting List Editors:', - 'service_body_editor_screen_sb_admin_editor_desc' => 'These Users Can Edit Any Meetings In This Service Body, But Only If They Are Unpublished.', - 'service_body_editor_screen_sb_admin_observer_label' => 'Observers:', - 'service_body_editor_screen_sb_admin_observer_desc' => 'These Users Can See Hidden Info (Like Email Addresses), But Cannot Edit Anything.', - 'service_body_dirty_confirm_text' => 'You have made changes to this Service Body. Do you want to lose your changes?', - 'service_body_save_button' => 'Save These Service Body Changes', - 'service_body_create_button' => 'Create This Service Body', - 'service_body_delete_button' => 'Delete This Service Body', - 'service_body_delete_perm_checkbox' => 'Delete This Service Body Permanently', - 'service_body_delete_button_confirm' => 'Are you sure that you want to delete this Service body? Make sure that all meetings are either removed or transferred to another service body before performing this function.', - 'service_body_delete_button_confirm_perm' => 'This Service body will be deleted permanently!', - 'service_body_change_fader_create_success_text' => 'The Service Body Was Successfully Created', - 'service_body_change_fader_create_fail_text' => 'The Service Body Create Failed', - 'service_body_change_fader_delete_success_text' => 'The Service Body Was Successfully Deleted', - 'service_body_change_fader_delete_fail_text' => 'The Service Body Delete Failed', - 'service_body_change_fader_fail_no_data_text' => 'The Service Body Change Failed, Because There Was No Data Supplied', - 'service_body_change_fader_fail_cant_find_sb_text' => 'The Service Body Change Failed, Because The Service Body Was Not Found', - 'service_body_change_fader_fail_cant_update_text' => 'The Service Body Change Failed, Because The Service Body Was Not Updated', - 'service_body_change_fader_fail_bad_hierarchy' => 'The Service Body Change Failed, Because The Selected Owner Service Body Is Under This Service Body, And Cannot Be Used', - 'service_body_cancel_button' => 'Restore To Original', - 'service_body_editor_type_label' => 'Service Body Type:', - 'service_body_editor_type_c_comdef_service_body__GRP__' => 'Group', - 'service_body_editor_type_c_comdef_service_body__COP__' => 'Co-Op', - 'service_body_editor_type_c_comdef_service_body__ASC__' => 'Area Service Committee', - 'service_body_editor_type_c_comdef_service_body__RSC__' => 'Regional Service Conference', - 'service_body_editor_type_c_comdef_service_body__WSC__' => 'World Service Conference', - 'service_body_editor_type_c_comdef_service_body__MAS__' => 'Metro Area', - 'service_body_editor_type_c_comdef_service_body__ZFM__' => 'Zonal Forum', - 'service_body_editor_type_c_comdef_service_body__GSU__' => 'Group Service Unit', - 'service_body_editor_type_c_comdef_service_body__LSU__' => 'Local Service Unit', - 'service_body_editor_screen_helpline_label' => 'Helpline:', - 'service_body_editor_screen_helpline_prompt' => 'Enter The Helpline Telephone Number', - 'service_body_editor_uri_naws_format_text' => 'Get The Meetings For This Service Body As A NAWS-Compatible File', - 'edit_Meeting_meeting_id' => 'Meeting ID:', - 'service_body_editor_create_new_sb_option' => 'Create A New Service Body', - 'service_body_editor_screen_world_cc_label' => 'World Committee Code:', - 'service_body_editor_screen_world_cc_prompt' => 'Enter A World Committee Code', - 'user_editor_disclosure' => 'User Administration', - 'user_editor_create_new_user_option' => 'Create A New User', - 'user_editor_screen_sb_id_label' => 'ID:', - 'user_editor_account_login_label' => 'User Login:', - 'user_editor_login_default_text' => 'Enter the User Login', - 'user_editor_account_type_label' => 'User Is A:', - 'user_editor_user_owner_label' => 'Owned By: ', - 'user_editor_account_type_1' => 'Server Administrator', - 'user_editor_account_type_2' => 'Service Body Administrator', - 'user_editor_account_type_3' => 'Service Body Editor', - 'user_editor_account_type_5' => 'Service Body Observer', - 'user_editor_account_type_4' => 'Disabled User', - 'user_editor_account_name_label' => 'User Name:', - 'user_editor_name_default_text' => 'Enter the User Name', - 'user_editor_account_description_label' => 'Description:', - 'user_editor_description_default_text' => 'Enter the User Description', - 'user_editor_account_email_label' => 'Email:', - 'user_editor_email_default_text' => 'Enter the User Email', - 'user_change_fader_success_text' => 'The User Was Successfully Changed', - 'user_change_fader_fail_text' => 'The User Change Failed', - 'user_change_fader_create_success_text' => 'The User Was Successfully Created', - 'user_change_fader_create_fail_text' => 'The User Create Failed', - 'user_change_fader_create_fail_already_exists' => 'A Login For The User That You Are Trying To Create Already Exists.', - 'user_change_fader_delete_success_text' => 'The User Was Successfully Deleted', - 'user_change_fader_delete_fail_text' => 'The User Delete Failed', - 'user_save_button' => 'Save the Changes to This User', - 'user_create_button' => 'Create This New User', - 'user_cancel_button' => 'Restore To Original', - 'user_delete_button' => 'Delete This User', - 'user_delete_perm_checkbox' => 'Delete This User Permanently', - 'user_password_label' => 'Change Password To:', - 'user_new_password_label' => 'Set Password To:', - 'user_password_default_text' => 'Leave This Alone, Unless You Want To Change The Password', - 'user_new_password_default_text' => 'You Must Enter A Password For A new User', - 'user_dirty_confirm_text' => 'You have made changes to this User. Do you want to lose your changes?', - 'user_delete_button_confirm' => 'Are you sure that you want to delete this user?', - 'user_delete_button_confirm_perm' => 'This user will be deleted permanently!', - 'user_create_password_alert_text' => 'New users must have a password. You have not supplied a password for this user.', - 'user_change_fader_fail_no_data_text' => 'The User Change Failed, Because There Was No Data Supplied', - 'user_change_fader_fail_cant_find_sb_text' => 'The User Change Failed, Because The User Was Not Found', - 'user_change_fader_fail_cant_update_text' => 'The User Change Failed, Because The User Was Not Updated', - 'format_editor_disclosure' => 'Format Administration', - 'format_change_fader_change_success_text' => 'The Format Was Successfully Changed', - 'format_change_fader_change_fail_text' => 'The Format Change Failed', - 'format_change_fader_create_success_text' => 'The Format Was Successfully Created', - 'format_change_fader_create_fail_text' => 'The Format Create Failed', - 'format_change_fader_delete_success_text' => 'The Format Was Successfully Deleted', - 'format_change_fader_delete_fail_text' => 'The Format Delete Failed', - 'format_change_fader_fail_no_data_text' => 'The Format Change Failed, Because There Was No Data Supplied', - 'format_change_fader_fail_cant_find_sb_text' => 'The Format Change Failed, Because The Format Was Not Found', - 'format_change_fader_fail_cant_update_text' => 'The Format Change Failed, Because The Format Was Not Updated', - 'format_editor_name_default_text' => 'Enter A Very Short Description', - 'format_editor_description_default_text' => 'Enter A More Detailed Description', - 'format_editor_create_format_button_text' => 'Create New Format', - 'format_editor_cancel_create_format_button_text' => 'Cancel', - 'format_editor_create_this_format_button_text' => 'Create This Format', - 'format_editor_change_format_button_text' => 'Change This Format', - 'format_editor_delete_format_button_text' => 'Delete This Format', - 'format_editor_reset_format_button_text' => 'Restore To Original', - 'need_refresh_message_fader_text' => 'You Should Refresh This Page Before Using This Section', - 'need_refresh_message_alert_text' => 'Because you have made changes in the Server Administration, Service Body Administration, User Administration, or Format Administration, the information displayed in this section may no longer be accurate, so the page needs to be refreshed. The easiest way to do this, is to Sign Out, then Log In again.', - 'format_editor_delete_button_confirm' => 'Are you sure that you want to delete this format?', - 'format_editor_delete_button_confirm_perm' => 'This format will be deleted permanently!', - 'format_editor_missing_key' => 'This format should have an entry for every language (at least a key).', // TODO: translate - 'format_editor_reserved_key' => 'This key is reserved for a venue type format - please use something different.', // TODO: translate - 'min_password_length_string' => 'The password is too short! It must be at least %d characters long!', - 'AJAX_Auth_Failure' => 'Authorization failed for this operation. There may be a problem with the server configuration.', - 'Maps_API_Key_Warning' => 'There is a problem with the Google Maps API Key.', - 'Maps_API_Key_Not_Set' => 'The Google Maps API key is not set.', - 'Observer_Link_Text' => 'Meeting Browser', - 'Data_Transfer_Link_Text' => 'Import Meeting Data (WARNING: Replaces Current Data!)', - 'MapsURL' => 'https://maps.google.com/maps?q=##LAT##,##LONG##+(##NAME##)&ll=##LAT##,##LONG##', - 'hidden_value' => 'Cannot Display Data -Unauthorized', - 'Value_Prompts' => array( - 'id_bigint' => 'Meeting ID', - 'worldid_mixed' => 'World Services ID', - 'service_body' => 'Service Body', - 'service_bodies' => 'Service Bodies', - 'weekdays' => 'Weekdays', - 'weekday' => 'Meeting Gathers Every', - 'start_time' => 'Meeting Starts at', - 'duration_time' => 'Meeting Lasts', - 'location' => 'Location', - 'duration_time_hour' => 'Hour', - 'duration_time_hours' => 'Hours', - 'duration_time_minute' => 'Minute', - 'duration_time_minutes' => 'Minutes', - 'lang_enum' => 'Language', - 'formats' => 'Formats', - 'distance' => 'Distance from Center', - 'generic' => 'NA Meeting', - 'close_title' => 'Close This Meeting Detail Window', - 'close_text' => 'Close Window', - 'map_alt' => 'Map to Meeting', - 'map' => 'Follow This Link for A Map', - 'title_checkbox_unpub_meeting' => 'This meeting is unpublished. It cannot be seen by regular searches.', - 'title_checkbox_copy_meeting' => 'This meeting is a duplicate of another meeting. It is also unpublished. It cannot be seen by regular searches.' - ), - 'world_format_codes_prompt' => 'NAWS Format:', - 'world_format_codes' => array( - '' => 'None', - 'OPEN' => 'Open', - 'CLOSED' => 'Closed', - 'WCHR' => 'Wheelchair-Accessible', - 'BEG' => 'Beginner/Newcomer', - 'BT' => 'Basic Text', - 'CAN' => 'Candlelight', - 'CPT' => '12 Concepts', - 'CW' => 'Children Welcome', - 'DISC' => 'Discussion/Participation', - 'GL' => 'Gay/Lesbian', - 'IP' => 'IP Study', - 'IW' => 'It Works Study', - 'JFT' => 'Just For Today Study', - 'LC' => 'Living Clean', - 'LIT' => 'Literature Study', - 'M' => 'Men', - 'MED' => 'Meditation', - 'NS' => 'Non-Smoking', - 'QA' => 'Questions & Answers', - 'RA' => 'Restricted Access', - 'S-D' => 'Speaker/Discussion', - 'SMOK' => 'Smoking', - 'SPK' => 'Speaker', - 'STEP' => 'Step', - 'SWG' => 'Step Working Guide Study', - 'TOP' => 'Topic', - 'TRAD' => 'Tradition', - 'VAR' => 'Format Varies', - 'W' => 'Women', - 'Y' => 'Young People', - 'LANG' => 'Alternate Language', - 'GP' => 'Guiding Principles', - 'NC' => 'No Children', - 'CH' => 'Closed Holidays', // TODO translate - 'VM' => 'Virtual', // TODO translate - 'HYBR' => 'Virtual and In-Person', // TODO translate - 'TC' => 'Temporarily Closed Facility', // TODO translate - 'SPAD' => 'Spiritual Principle a Day', // TODO translate - ), - 'format_type_prompt' => 'Format Type:', - 'format_type_codes' => array( - '' => 'None', - 'FC1' => 'Meeting Format (Speaker, Book Study, etc.)', - 'FC2' => 'Location Code (Wheelchair Accessible, Limited Parking, etc.)', - 'FC3' => 'Common Needs and Restrictions (Mens Meeting, LGTBQ, No Children, etc.)', - 'O' => 'Attendance by non-addicts (Open, Closed)', - 'LANG' => 'Language', - 'ALERT' => 'Format should be especially prominent (Clean requirement, etc.)', - ), - - 'cookie_monster' => 'This site uses a cookie to store your preferred language.', - 'main_prompts' => array( - 'id_bigint' => 'ID', - 'worldid_mixed' => 'World ID', - 'shared_group_id_bigint' => 'Unused', - 'service_body_bigint' => 'Service Body ID', - 'weekday_tinyint' => 'Weekday', - 'venue_type' => 'Venue Type', - 'start_time' => 'Start Time', - 'duration_time' => 'Duration', - 'time_zone' => 'Time Zone', - 'formats' => 'Formats', - 'lang_enum' => 'Language', - 'longitude' => 'Longitude', - 'latitude' => 'Latitude', - 'published' => 'Published', - 'email_contact' => 'Email Contact', - ), - 'check_all' => 'Check All', - 'uncheck_all' => 'Uncheck All', - 'automatically_calculated_on_save' => 'Automatically calculated on save.' -); - -$email_contact_strings = array( - 'meeting_contact_form_subject_format' => "[MEETING LIST CONTACT] %s", - 'meeting_contact_message_format' => "%s\n--\nThis message concerns the meeting named \"%s\", which meets at %s, on %s.\nBrowser Link: %s\nEdit Link: %s\nIt was sent directly from the meeting list web server, and the sender is not aware of your email address.\nPlease be aware that replying will expose your email address.\nIf you use \"Reply All\", and there are multiple email recipients, you may expose other people's email addresses.\nPlease respect people's privacy and anonymity; including the original sender of this message." -); - -$change_type_strings = array( - '__THE_MEETING_WAS_CHANGED__' => 'The meeting was changed.', - '__THE_MEETING_WAS_CREATED__' => 'The meeting was created.', - '__THE_MEETING_WAS_DELETED__' => 'The meeting was deleted.', - '__THE_MEETING_WAS_ROLLED_BACK__' => 'The meeting was rolled back to a previous version.', - - '__THE_FORMAT_WAS_CHANGED__' => 'The format was changed.', - '__THE_FORMAT_WAS_CREATED__' => 'The format was created.', - '__THE_FORMAT_WAS_DELETED__' => 'The format was deleted.', - '__THE_FORMAT_WAS_ROLLED_BACK__' => 'The format was rolled back to a previous version.', - - '__THE_SERVICE_BODY_WAS_CHANGED__' => 'The service body was changed.', - '__THE_SERVICE_BODY_WAS_CREATED__' => 'The service body was created.', - '__THE_SERVICE_BODY_WAS_DELETED__' => 'The service body was deleted.', - '__THE_SERVICE_BODY_WAS_ROLLED_BACK__' => 'The service body was rolled back to a previous version.', - - '__THE_USER_WAS_CHANGED__' => 'The user was changed.', - '__THE_USER_WAS_CREATED__' => 'The user was created.', - '__THE_USER_WAS_DELETED__' => 'The user was deleted.', - '__THE_USER_WAS_ROLLED_BACK__' => 'The user was rolled back to a previous version.', - - '__BY__' => 'by', - '__FOR__' => 'for' -); - -$detailed_change_strings = array( - 'was_changed_from' => 'was changed from', - 'to' => 'to', - 'was_changed' => 'was changed', - 'was_added_as' => 'was added as', - 'was_deleted' => 'was deleted', - 'was_published' => 'The meeting was published', - 'was_unpublished' => 'The meeting was unpublished', - 'formats_prompt' => 'The meeting format', - 'duration_time' => 'The meeting duration', - 'start_time' => 'The meeting start time', - 'longitude' => 'The meeting longitude', - 'latitude' => 'The meeting latitude', - 'sb_prompt' => 'The meeting changed its Service Body from', - 'id_bigint' => 'The meeting ID', - 'lang_enum' => 'The meeting language', - 'worldid_mixed' => 'The World Committee Code', - 'weekday_tinyint' => 'The day of the week on which the meeting gathers', - 'non_existent_service_body' => 'Service Body No Longer Exists', -); - -defined('_END_CHANGE_REPORT') or define('_END_CHANGE_REPORT', '.'); diff --git a/src/legacy/local_server/server_admin/lang/fr/data_transfer_strings.php b/src/legacy/local_server/server_admin/lang/fr/data_transfer_strings.php deleted file mode 100755 index 6fa2303ec..000000000 --- a/src/legacy/local_server/server_admin/lang/fr/data_transfer_strings.php +++ /dev/null @@ -1,22 +0,0 @@ -.*/ - defined('BMLT_EXEC') or die('Cannot Execute Directly'); // Makes sure that this file is in the correct context. - - $comdef_data_transfer_strings = array (); diff --git a/src/legacy/local_server/server_admin/lang/fr/install_wizard_strings.php b/src/legacy/local_server/server_admin/lang/fr/install_wizard_strings.php deleted file mode 100644 index 80ed92be9..000000000 --- a/src/legacy/local_server/server_admin/lang/fr/install_wizard_strings.php +++ /dev/null @@ -1,138 +0,0 @@ -.*/ - defined('BMLT_EXEC') or die('Ne peut pas s\exécuter directement'); // Makes sure that this file is in the correct context. - - global $comdef_install_wizard_strings; - - $comdef_install_wizard_strings = array ( - 'Database_Version_Error' => 'ERREUR: Vous devez avoir la version de PHP 5.6 ou superieur installe sur ce serveur!', - 'Database_PDO_Error' => 'ERREUR: Vous n\'avez pas installé PHP PDO!', - 'Database_Type_Error' => 'ERREUR: Vous n\'avez pas Installe PHP PDO!', - 'Database_TestButton_Text' => 'TEST', - 'Database_TestButton_Success' => 'La connexion de base de données a reussi.', - 'Database_TestButton_Fail' => 'La connexion de base de données a echoue:', - 'Database_TestButton_Fail2' => 'La connexion de base de données a echoue car il existe deja une base de donnees initialisee.', - 'Database_Whitespace_Note' => 'Warning: %s has whitespace at the beginning or end.', - - 'AJAX_Handler_DB_Connect_Error' => 'La connexion de base de données a échoué! S\'il vous plaît assurez-vous que la base de données existe, est complètement vide, l\'utilisateur est créé, et que l\'utilisateur dispose des autorisations complètes sur la base de données vide.', - 'AJAX_Handler_DB_Established_Error' => 'La base de données esists déjà, et a été mis en place! Vous ne pouvez pas utiliser cette configuration pour écraser une base existante!', - 'AJAX_Handler_DB_Incomplete_Error' => 'Il n\'y a pas assez d\'informations pour initialiser la base de données!', - - 'NoDatabase_Note_AlreadySet' => 'Il existe déjà une base de données existante, de sorte que vous ne peut pas initialiser de nouveau.', - 'NoDatabase_Note_PasswordIssue' => 'Vous devez créer un compte d\'administrateur du serveur avant que la base de données peut être initialisé.', - 'NoServerAdmin_Note_AlreadySet' => 'Il existe déjà une base de données existante, donc vous ne pouvez pas configurer un compte d\'administrateur de serveur (Il en existe un déjà).', - 'NeedLongerPasswordNote' => 'Ce mot de passe est trop court. Il doit être au moins de %d caractères.', - - 'Prev_Button' => 'PRÉCÉDENT', - 'Next_Button' => 'SUIVANT', - - 'Page_1_Tab' => 'ÉTAPE 1: Basse de donnée', - 'Page_1_Heading' => 'Réglages de base de données de connexion', - 'Page_1_Text' => 'Avant de pouvoir appliquer les paramètres de cette page, vous devez mettre en place une nouvelle base de données complètement vide, et d\'établir une base de données utilisateur disposant de droits d\'accès complets sur cette base de données.', - - 'Database_Name' => 'Nom de la base de donnée:', - 'Database_Name_Default_Text' => 'Entrer le Nom de la base de donnée', - 'Database_Type' => 'Type de la base de données:', - 'Database_Host' => 'Hôte de la base de données:', - 'Database_Host_Default_Text' => 'Entrer Hôte de la base de données:', - 'Database_Host_Additional_Text' => 'Normalement c\'est "localhost."', - 'Table_Prefix' => 'Préfixe de la Table:', - 'Table_Prefix_Default_Text' => 'Entrer un Préfixe de la Table:', - 'Table_Prefix_Additional_Text' => 'Seulement pour les serveurs racines multiples partageant une base de données.', - 'Database_User' => 'nom d\'utilisateur la base de données:', - 'Database_User_Default_Text' => 'Entrer le nom d\'utilisateur la base de données', - 'Database_PW' => 'Mot de Passe de la Base de Données:', - 'Database_PW_Default_Text' => 'Entrer le Mot de Passe de la Base de Données', - 'Database_PW_Additional_Text' => 'Faite à ce qu\'il en soit vraiment sécuritaire.', - - 'Maps_API_Key_Warning' => 'There is a problem with the Google Maps API Key.', - - 'Page_2_Tab' => 'ÉTAPE 2: Localisation par défaut', - 'Page_2_Heading' => 'Regler la localisation innitiale pour les Réunions', - 'Page_2_Text' => 'When saving a meeting, the BMLT Root Server uses the Google Maps API to determine the latitude and longitude for the meeting address. These settings are required to allow the BMLT Root Server to communicate with the Google Maps API.', - - 'Page_3_Tab' => 'ÉTAPE 3: Paramètres du serveur', - 'Page_3_Heading' => 'Définissez les paramètres généraux du serveur', - 'Page_3_Text' => 'Ce sont quelques paramètres qui affectent l\'administration et la configuration générale de ce serveur. La plupart des paramètres du serveur sont effectuées sur le serveur lui-même.', - 'Admin_Login' => 'Compte Administraterur du Serveur:', - 'Admin_Login_Default_Text' => 'Entrer le Compte Administraterur du Serveur', - 'Admin_Login_Additional_Text' => 'Il s\'agit de la chaîne de connexion de l\'administrateur du serveur.', - 'Admin_Password' => 'Mot de passe administrateur du serveur:', - 'Admin_Password_Default_Text' => 'Entrer le Mot de passe administrateur du serveur', - 'Admin_Password_Additional_Text' => 'Assurez-vous qu\'il s\'agit d\'un mot de passe non négligeable! Il a beaucoup de puissance! (Aussi, ne l\'oubliez pas).', - 'ServerAdminName' => 'SAdministrateur du serveur', - 'ServerAdminDesc' => 'Principale Administrateur du serveur', - 'ServerLangLabel' => 'Langue du Serveur par défaut:', - 'DistanceUnitsLabel' => 'Unités de distance:', - 'DistanceUnitsMiles' => 'Miles', - 'DistanceUnitsKM' => 'Kilomètres', - 'SearchDepthLabel' => 'Densité des réunions pour la recherche automatique:', - 'SearchDepthText' => 'Il s\'agit d\'une approximation du nombre de rencontres qui devront être trouvée dans la sélection automatique du rayon. Plus de réunions est signifie un plus grand rayon.', - 'HistoryDepthLabel' => 'Nombre de sauvegardes de changements pour une réunion:', - 'HistoryDepthText' => 'Le plus l\'historique est, plus la base de données en deviendra.', - 'TitleTextLabel' => 'Le titre de l\'écran d\'administration:', - 'TitleTextDefaultText' => 'Saisissez un titre court de l\'édition Page de Connexion', - 'BannerTextLabel' => 'Invite de la Connexion pour l\'administration:', - 'BannerTextDefaultText' => 'Entrez une invite courte pour la page de connexion', - 'RegionBiasLabel' => 'Biais de région:', - 'PasswordLengthLabel' => 'Longueur Minimale de Mot de passe:', - 'PasswordLengthExtraText' => 'Cela affectera également le mot de passe de l\'administrateur du serveur, ci-dessus.', - 'DurationLabel' => 'Durée par défaut de la réunion:', - 'DurationHourLabel' => 'Heures', - 'DurationMinutesLabel' => 'Minutes', - 'LanguageSelectorEnableLabel' => 'Display Language Selector On Login:', - 'LanguageSelectorEnableExtraText' => 'If you select this, a popup menu will appear in the login screen, so administrators can select their language.', - 'EmailContactEnableLabel' => 'Allow Email Contacts From Meetings:', - 'EmailContactEnableExtraText' => 'If you select this, site visitors will be able to send emails from meeting records.', - - 'Page_4_Tab' => 'Étape 4: Enregistrer les paramètres', - 'Page_4_Heading' => 'Créer le fichier de paramètres', - 'Page_4_Text' => 'Pour des raisons de sécurité (Oui, nous sommes assez paranoïaque - allez figure donc..), ce programme ne tentera pas de créer ou modifier le fichier de paramètres. Au lieu de cela, nous vous demandons de créer vous-même, via FTP ou un gestionnaire de fichiers panneau de contrôle, le nommer "auto-config.inc.php", et collez le texte suivant dans le fichier:', - - 'DefaultPasswordLength' => 10, - 'DefaultMeetingCount' => 10, - 'DefaultChangeDepth' => 5, - 'DefaultDistanceUnits' => 'mi', - 'DefaultDurationTime' => '01:30:00', - 'DurationTextInitialText' => 'Les Réunions de NA durent généralement de 90 minutes (une heure et demie), sauf indication contraire.', - 'time_format' => 'g:i A', - 'change_date_format' => 'g:i A, n/j/Y', - 'BannerTextInitialText' => 'Connexion administration', - 'TitleTextInitialText' => 'Basic Meeting List Toolbox Administration', - 'DefaultRegionBias' => 'us', - 'search_spec_map_center' => array ( 'longitude' => -118.563659, 'latitude' => 34.235918, 'zoom' => 6 ), - 'DistanceChoices' => array ( 2, 5, 10, 20, 50 ), - 'HistoryChoices' => array ( 1, 2, 3, 5, 8, 10, 15 ), - 'PW_LengthChices' => array ( 6, 8, 10, 12, 16 ), - 'ServerAdminDefaultLogin' => 'serveradmin', - - 'Explanatory_Text_1_Initial_Intro' => 'Cet assistant d\'installation vous guidera à travers le processus de création d\'une base de données initiale, ainsi que d\'un fichier de configuration. Dans la dernière étape, nous allons créer un fichier de paramètres, et initialiser une base de données vide.', - 'Explanatory_Text_1_DB_Intro' => 'La première chose que vous devez faire, c\'est de créer une nouvelle base de données vide, et un utilisateur de base de données qui a accès à cette base de données. Cela se fait habituellement par l\'intermédiaire de votre site Web Panneau de configuration. Une fois que vous avez créé la base de données, vous devez saisir les informations relatives à cette base de données dans les éléments de texte sur cette page.', - - 'Explanatory_Text_2_Region_Bias_Intro' => 'The "Region Bias" is a code that is sent to Google when a location search is done, and can help Google to make sense of ambiguous search queries.', - - 'Explanatory_Text_3_Server_Admin_Intro' => 'L\'administrateur du serveur est le principal utilisateur pour le serveur. Il est le seul compte qui peut créer de nouveaux utilisateurs et les structures de service, et est très puissant. Vous devez créer un identifiant et un mot de passe non négligeable pour ce compte. Vous serez en mesure de modifier les autres aspects du compte sur le serveur principal, une fois la base de données a été mis en place.', - 'Explanatory_Text_3_Misc_Intro' => 'Ce sont les différents paramètres qui influent sur la façon dont le serveur racine se comporte et apparaît.', - - 'Explanatory_Text_4_Main_Intro' => 'Si vous avez entré les informations de base de données, et si vous avez spécifié les informations de connexion de l\'administrateur du serveur, vous pouvez initialiser la base de données ici. Rappelez-vous que la base de données doit être complètement vide de tables pour le Serveur BMLT racine. (Il peut avoir des tables pour d\'autres serveurs ou services).', - 'Explanatory_Text_4_NAWS_Export' => 'Optionally, you can import the meetings from a NAWS export spreadsheet. Uncheck the box to initialize them to \'unpublished\'. (This is useful if many of the new meetings will need to be edited or deleted, and you don\'t want them showing up in the meantime.)', - 'Explanatory_Text_4_File_Intro' => 'Le texte ci-dessous est le code source de PHP pour le fichier de paramètres principaux. Vous aurez besoin de créer un fichier sur le serveur avec ce texte dedans. Le fichier est au même niveau que le répertoire du serveur principal pour le serveur racine.', - 'Explanatory_Text_4_File_Extra' => 'Vous devez également vous assurer que les autorisations de fichiers sont limités (chmod 0644). Cela empêche le fichier d\'être écrite, et le serveur racine ne fonctionnera que si le fichier dispose des autorisations nécessaires.', - 'Page_4_PathInfo' => 'Le fichier doit être placé comme %s/auto-config.inc.php, ce qui est l\'endroit où le répertoire de votre %s est. Une fois le fichier a été créé et vous avez mis le texte ci-dessus dedans, vous devez exécuter la commande suivante pour vous assurer que les autorisations sont correctes:', - 'Page_4_Final' => 'Une fois tout cela terminé, actualisez cette page, et vous devriez voir la page de connexion du serveur racine.', - 'FormatLangNamesLabel' => 'Enter extra languages in format code1:name1 (example "fa:farsi ru:russian"):', - ); diff --git a/src/legacy/local_server/server_admin/lang/fr/name.txt b/src/legacy/local_server/server_admin/lang/fr/name.txt deleted file mode 100644 index 51b49cf3d..000000000 --- a/src/legacy/local_server/server_admin/lang/fr/name.txt +++ /dev/null @@ -1 +0,0 @@ -Français \ No newline at end of file diff --git a/src/legacy/local_server/server_admin/lang/fr/server_admin_strings.inc.php b/src/legacy/local_server/server_admin/lang/fr/server_admin_strings.inc.php deleted file mode 100755 index 5c4c60fdb..000000000 --- a/src/legacy/local_server/server_admin/lang/fr/server_admin_strings.inc.php +++ /dev/null @@ -1,488 +0,0 @@ -. */ - -defined('BMLT_EXEC') or die('Cannot Execute Directly'); // Makes sure that this file is in the correct context. - -$comdef_server_admin_strings = array('server_admin_disclosure' => 'Administration Serveur', - 'server_admin_naws_spreadsheet_label' => 'Mise à jour de la feuille de calcul des codes du comité mondial', - 'update_world_ids_button_text' => 'Mise à jour des codes du comité mondial ', - 'update_world_ids_from_spreadsheet_dropdown_text' => 'Mise à jour des codes du comité mondial (IDs de groupe de NAWS) à partir de la feuille de calcul de NAWS', - 'server_admin_error_no_world_ids_updated' => 'Aucun ID mondial n\'a été mis à jour. Cela peut être dû au fait que votre utilisateur n\'a pas l\'autorisation de mettre à jour les réunions soumises.', - 'server_admin_error_required_spreadsheet_column' => 'La colonne requise n\'existe pas dans la feuille de calcul:', - 'server_admin_error_bmlt_id_not_integer' => 'Le bmlt_id fourni n\'est pas un nombre entier: ', - 'server_admin_error_could_not_create_reader' => 'Impossible de créer un lecteur pour le fichier: ', - 'server_admin_error_no_files_uploaded' => 'Aucun fichier n\'a été téléchargé.', - 'server_admin_error_service_bodies_already_exist' => 'Les structures de service avec les ID mondiaux suivants existent déjà: ', - 'server_admin_error_meetings_already_exist' => 'Des réunions avec les identifiants mondiaux suivants existent déjà: ', - 'server_admin_ui_num_meetings_updated' => 'Nombre de réunions mises à jour: ', - 'server_admin_ui_num_meetings_not_updated' => 'Nombre de réunions qui n\'ont pas besoin d\'être mises à jour: ', - 'server_admin_ui_warning' => 'ATTENTION', - 'server_admin_ui_errors' => 'Erreur(s)', - 'server_admin_ui_deleted_meetings_marked' => 'Nombre de réunions supprimées, marquées de manière à ce qu\'elles n\'apparaissent pas dans les futures exportations des NAWS', - 'server_admin_ui_problem_meetings' => 'Des réunions ont été trouvées dans la feuille de calcul qui n\'ont pas pu être mises à jour. ID des réunions problématiques: ', - 'server_admin_ui_service_bodies_created' => 'Structures de service créées: ', - 'server_admin_ui_meetings_created' => 'Réunions créées: ', - 'server_admin_ui_users_created' => 'Utilisateurs créés: ', - 'server_admin_ui_refresh_ui_text' => 'Déconnectez-vous, puis reconnectez-vous pour voir les nouvelles structures de service, utilisateurs et réunions.', - 'import_service_bodies_and_meetings_button_text' => 'Importer les structures de service et les réunions', - 'import_service_bodies_and_meetings_dropdown_text' => 'Importer les structures de service et les réunions depuis l\'export NAWS', - 'server_admin_naws_import_spreadsheet_label' => 'Import de la feuille de calcul NAWS :', - 'server_admin_naws_import_initially_publish' => 'Initialiser les réunions importées à \'publiée\': ', - 'server_admin_naws_import_explanation' => 'Décochez la case pour initialiser les réunions importées à \'non publiée\'. (Cette fonction est utile si un grand nombre de nouvelles réunions doivent être modifiées ou supprimées et que vous ne voulez pas qu\'elles apparaissent entre-temps.)', - 'account_disclosure' => 'Mon compte', - 'account_name_label' => 'Mon nom de compte:', - 'account_login_label' => 'Mon Login:', - 'account_type_label' => 'Je suis un:', - 'account_type_1' => 'Administrateur du Serveur', - 'account_type_2' => 'Administrateur d\'une structure de service', - 'ServerMapsURL' => 'https://maps.googleapis.com/maps/api/geocode/xml?address=##SEARCH_STRING##&sensor=false', - 'account_type_4' => 'Pathetic Luser Who Shouldn\'t Even Have Access to This Page -The Author of the Software Pooched it BAD!', - 'account_type_5' => 'Observateur', - 'change_password_label' => 'Changer mon mot de passe pour:', - 'change_password_default_text' => 'Laissez libre si vous ne voulez pas changer votre mot de passe', - 'account_email_label' => 'Mon adresse e-mail:', - 'email_address_default_text' => 'Saisissez une adresse e-mail', - 'account_description_label' => 'ma description:', - 'account_description_default_text' => 'Entrez une description', - 'account_change_button_text' => 'Modifier mes paramètres de compte', - 'account_change_fader_success_text' => 'L\'information du compte a été changé avec succès', - 'account_change_fader_failure_text' => 'L\'information du compte n\'a pas été modifié', - 'meeting_editor_disclosure' => 'Éditeur de réunion', - 'meeting_editor_already_editing_confirm' => 'Vous êtes en train d\'éditer une autre réunion. Voulez-vous perdre tous les changements de cette réunion?', - 'meeting_change_fader_success_text' => 'La réunion a été changé avec succès', - 'meeting_change_fader_failure_text' => 'La réunion n\'a pas été modifié', - 'meeting_change_fader_success_delete_text' => 'La réunion a été supprimé avec succès', - 'meeting_change_fader_fail_delete_text' => 'La réunion n\'a pas été supprimé', - 'meeting_change_fader_success_add_text' => 'La nouvelle réunion a été ajouté avec succès', - 'meeting_change_fader_fail_add_text' => 'La nouvelle réunion n\'a pas été ajouté', - 'meeting_text_input_label' => 'Recherche contextuelle:', - 'access_service_body_label' => 'J\'ai accès à:', - 'meeting_text_input_default_text' => 'Saisissez un mot-clé pour la recherche contextuelle', - 'meeting_text_location_label' => 'Il s\'agit d\'une Ville ou code postal', - 'meeting_search_weekdays_label' => 'Recherche par jour de semaine:', - 'meeting_search_weekdays_names' => array('Tous', 'Dimanche', 'Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi'), - 'meeting_search_service_bodies_label' => 'Choisir parmi les comités:', - 'meeting_search_start_time_label' => 'Recherche par réunion Heure de début:', - 'meeting_search_start_time_all_label' => 'N\'importe quand', - 'meeting_search_start_time_morn_label' => 'Matin', - 'meeting_search_start_time_aft_label' => 'Après-midi', - 'meeting_search_start_time_eve_label' => 'Soir', - 'meeting_search_no_results_text' => 'Pas de réunions trouvés', - 'meeting_editor_tab_specifier_text' => 'Rechercher des Réunions', - 'meeting_editor_tab_editor_text' => 'Modifier Réunions', // TODO: change to 'Edit Or Create Meetings' - 'meeting_editor_create_new_text' => 'Créer une nouvelle réunion', - 'meeting_editor_location_map_link' => 'Carte de localisation', - 'meeting_editor_screen_match_ll_button' => 'Optimiser la longitude et la latitude par rapport cette adresse', - 'meeting_editor_screen_default_text_prompt' => 'Entrez du texte ou un nombre', - 'meeting_is_published' => 'La réunion est publiée', - 'meeting_unpublished_note' => 'Note: La dépublication d\'une réunion indique une fermeture temporaire. Si cette réunion est définitivement fermée, veuillez la supprimer.', - 'meeting_editor_screen_meeting_name_label' => 'Nom de réunion:', - 'meeting_editor_screen_meeting_name_prompt' => 'Entrer un nom de réunion', - 'meeting_editor_screen_meeting_weekday_label' => 'jour de la semaine:', - 'meeting_editor_screen_meeting_start_label' => 'Réunion Heure de début:', - 'meeting_editor_screen_meeting_time_zone_label' => 'Fuseau horaire de la réunion:', - 'meeting_editor_screen_meeting_am_label' => 'Matin', - 'meeting_editor_screen_meeting_pm_label' => 'Après-midi', - 'meeting_editor_screen_meeting_noon_label' => 'Midi', - 'meeting_editor_screen_meeting_midnight_label' => 'Minuit', - 'meeting_editor_screen_meeting_duration_label' => 'Durée:', - 'meeting_editor_screen_meeting_oe_label' => 'À composition non limitée:', - 'meeting_editor_screen_meeting_cc_label' => 'Code Comité mondial:', - 'meeting_editor_screen_meeting_cc_advice' => 'Normalement, ne touchez pas à ce champ (voir la documentation).', - 'meeting_editor_screen_meeting_contact_label' => 'Contact E-mail de la réunion:', - 'meeting_editor_screen_meeting_contact_prompt' => 'Entrez un E-mail pour un contact spécifique uniquement de cette réunion', - 'meeting_editor_screen_meeting_sb_label' => 'composante de structure de service:', - 'meeting_editor_screen_meeting_sb_default_value' => 'Sans sélection de composante de structure de service', - 'meeting_editor_screen_meeting_longitude_label' => 'Longitude:', - 'meeting_editor_screen_meeting_longitude_prompt' => 'Entrer la Longitude', - 'meeting_editor_screen_meeting_latitude_label' => 'Latitude:', - 'meeting_editor_screen_meeting_latitude_prompt' => 'Entrer la Latitude', - 'meeting_editor_screen_meeting_location_label' => 'Emplacement:', - 'meeting_editor_screen_meeting_location_prompt' => 'Entrez le nom de l\'emplacement nom (comme un nom d\'édifice)', - 'meeting_editor_screen_meeting_info_label' => 'Détails:', - 'meeting_editor_screen_meeting_info_prompt' => 'Entrer infomations additionels de l\'emplacement', - 'meeting_editor_screen_meeting_street_label' => 'Adresse:', - 'meeting_editor_screen_meeting_street_prompt' => 'Entrer l\'adresse', - 'meeting_editor_screen_meeting_neighborhood_label' => 'Quartier:', - 'meeting_editor_screen_meeting_neighborhood_prompt' => 'Entrer le nom du quartier (Pas d\'arrondissement ni de secteur)', - 'meeting_editor_screen_meeting_borough_label' => 'L\'arrondissement de la ville ou secteur:', - 'meeting_editor_screen_meeting_borough_prompt' => 'Entrer un nom d\'arrondissement ou de secteur (Pas de quartier)', - 'meeting_editor_screen_meeting_city_label' => 'Ville / Municipalité:', - 'meeting_editor_screen_meeting_city_prompt' => 'Entrer le nom d\'une ville ou Municipalité (Pas de compté ni d\'arrondissement)', - 'meeting_editor_screen_meeting_county_label' => 'Compté / Région:', - 'meeting_editor_screen_meeting_county_prompt' => 'Entrer le nom de Compté ou de Région', - 'meeting_editor_screen_meeting_state_label' => 'Province:', - 'meeting_editor_screen_meeting_state_prompt' => 'Entrer le mom de la Province', - 'meeting_editor_screen_meeting_zip_label' => 'Code Postal:', - 'meeting_editor_screen_meeting_zip_prompt' => 'Entrer le Code Postal', - 'meeting_editor_screen_meeting_nation_label' => 'Pays:', - 'meeting_editor_screen_meeting_nation_prompt' => 'Entrer le nom de Pays', - 'meeting_editor_screen_meeting_comments_label' => 'Commentaires:', - 'meeting_editor_screen_meeting_train_lines_label' => 'Lignes de train:', - 'meeting_editor_screen_meeting_bus_lines_label' => 'Ligne de bus:', - 'meeting_editor_screen_meeting_phone_meeting_number_label' => 'Numéro d\'appel de la réunion téléphonique:', - 'meeting_editor_screen_meeting_phone_meeting_number_prompt' => 'Entrez le numéro d\'appel pour une réunion téléphonique ou virtuelle.', - 'meeting_editor_screen_meeting_virtual_meeting_link_label' => 'Lien vers la réunion virtuelle', - 'meeting_editor_screen_meeting_virtual_meeting_link_prompt' => 'Entrer le lien de la réunion virtuelle', - 'meeting_editor_screen_meeting_virtual_meeting_additional_info_label' => 'Informations supplémentaires de la réunion virtuelle:', - 'meeting_editor_screen_meeting_virtual_meeting_additional_info_prompt' => 'Saisissez toute information supplémentaire pour rejoindre la réunion virtuelle, y compris directement depuis l\'application. Par exemple, si la réunion utilise Zoom, "Zoom ID : 456 033 8613, Mot de passe : 1953" serait approprié.', - 'meeting_editor_screen_meeting_venue_type' => 'Type de réunion:', - 'meeting_editor_screen_meeting_venue_type_inperson' => 'Physique', - 'meeting_editor_screen_meeting_venue_type_virtual' => 'Virtuelle', - 'meeting_editor_screen_meeting_venue_type_virtualTC' => 'Virtuelle (remplace temporairement une réunion physique)', - 'meeting_editor_screen_meeting_venue_type_hybrid' => 'Hybride (À la fois physique et virtuelle)', - 'meeting_editor_screen_meeting_venue_type_validation' => 'Vous devez sélectionner un type de réunion.', - 'meeting_editor_screen_meeting_virtual_info_missing' => 'Les réunions virtuelles ou hybrides doivent avoir un lien de réunion, un numéro d\'appel de réunion ou des informations supplémentaires sur la réunion virtuelle.', - 'meeting_editor_screen_meeting_location_warning' => 'La réunion doit avoir un lieu (au moins une ville et un état/province, ou un code postal).', - 'meeting_editor_screen_meeting_address_warning' => 'Les réunions physiques ou hybrides doivent avoir une adresse.', - 'meeting_editor_screen_meeting_url_validation' => 'Le lien pour la réunion virtuelle n\'est pas une URL valide', - 'meeting_editor_screen_meeting_url_or_phone_warning' => 'Les réunions virtuelles ou hybrides doivent comporter soit un lien vers une réunion virtuelle, soit un numéro d\'appel pour une réunion téléphonique.', - 'meeting_editor_screen_meeting_additional_warning' => 'Veuillez également remplir le formulaire Informations supplémentaires sur la réunion virtuelle s\'il existe un lien vers une réunion virtuelle.', - 'meeting_editor_screen_in_person_virtual_info_warning' => 'Les réunions physiques ne devraient pas avoir d\'informations sur les réunions virtuelles.', - 'meeting_editor_screen_meeting_virtual_location_info_warning' => 'Les réunions virtuelles ne devraient pas avoir de nom ou d\'adresse de lieu.', - 'meeting_editor_screen_meeting_validation_warning' => 'Il y a des avertissements. Êtes-vous sûr de vouloir quand même enregistrer ? Si non, appuyez sur "Annuler" et allez dans l\'onglet Emplacement pour voir les avertissements et les traiter.', - 'meeting_editor_screen_meeting_validation_failed' => 'Impossible d\'enregistrer en raison d\'erreurs de saisie. Veuillez vous rendre dans l\'onglet Emplacement pour les corriger, puis réessayer d\'enregistrer. Erreurs: ', - 'meeting_editor_screen_meeting_validation_warnings' => 'Avertissements de saisie affichés dans l\'onglet Emplacement: ', - 'meeting_editor_screen_meeting_contact_name_1_label' => 'Contact 1 Nom:', - 'meeting_editor_screen_meeting_contact_email_1_label' => 'Contact 1 Email:', - 'meeting_editor_screen_meeting_contact_phone_1_label' => 'Contact 1 Téléphone:', - 'meeting_editor_screen_meeting_contact_name_2_label' => 'Contact 2 Nom:', - 'meeting_editor_screen_meeting_contact_email_2_label' => 'Contact 2 Email:', - 'meeting_editor_screen_meeting_contact_phone_2_label' => 'Contact 2 Téléphone:', - 'meeting_editor_screen_meeting_publish_search_prompt' => 'Rechercher:', - 'meeting_editor_screen_meeting_publish_search_pub' => 'Réunions publiées seulement', - 'meeting_editor_screen_meeting_publish_search_unpub' => 'Réunions non-publiées seulement', - 'meeting_editor_screen_meeting_visibility_advice' => 'Ce n\'est jamais affiché dans les recherches de réunion normales.', - 'meeting_editor_screen_meeting_publish_search_all' => 'Toutes les réunions', - 'meeting_editor_screen_meeting_create_button' => 'Créer une nouvelle réunion', - 'meeting_editor_screen_delete_button' => 'Supprimer cette réunion', - 'meeting_editor_screen_delete_button_confirm' => 'Etes-vous sûr que vous voulez supprimer cette rencontre?', - 'meeting_editor_screen_cancel_button' => 'Annuler', - 'logout' => 'Déconnexion', - 'meeting_editor_screen_cancel_confirm' => 'Etes-vous sûr que vous voulez annuler l\'édition de cette réunion, et perdre tous les changements?', - 'meeting_lookup_failed' => 'La recherche d\'adresse a échoué.', - 'meeting_lookup_failed_not_enough_address_info' => 'Il n\'y a pas assez d\'informations d\'adresse valide pour en faire une recherche.', - 'meeting_create_button_name' => 'L\'enregistrer comme une nouvelle réunion', - 'meeting_saved_as_a_copy' => 'Sauvegarder cette réunion comme une copie (crée une nouvelle réunion)', - 'meeting_save_buttonName' => 'Enregistrez les modifications à cette réunion', - 'meeting_editor_tab_bar_basic_tab_text' => 'de Base', - 'meeting_editor_tab_bar_location_tab_text' => 'Localisation', - 'meeting_editor_tab_bar_format_tab_text' => 'Format', - 'meeting_editor_tab_bar_other_tab_text' => 'Autre', - 'meeting_editor_tab_bar_history_tab_text' => 'Historique', - 'meeting_editor_result_count_format' => '%d de réunions trouvées', - 'meeting_id_label' => 'ID de réunions:', - 'meeting_editor_default_zoom' => '13', - 'meeting_editor_default_weekday' => '2', - 'meeting_editor_default_start_time' => '20:30:00', - 'login_banner' => 'Basic Meeting List Toolbox', - 'login_underbanner' => 'Console d\'Administration de serveur racine', - 'login' => 'ID de connexion', - 'password' => 'Mot de passe', - 'button' => 'Connexion', - 'cookie' => 'Vous devez activer les cookies dans le but d\'administrer ce serveur.', - 'noscript' => 'Vous ne pouvez pas administrer ce site sans JavaScript.', - 'title' => 'S\'il vous plaît vous identifier pour administrer le serveur.', - 'edit_Meeting_object_not_found' => 'ERREUR: La réunion n\'a pas été trouvée.', - 'edit_Meeting_object_not_changed' => 'ERREUR: La réunion n\'a pas été modifiée.', - 'edit_Meeting_auth_failure' => 'Vous n\'êtes pas autorisé à modifier cette réunion.', - 'not_auth_1' => 'NON AUTHORISÉ', - 'not_auth_2' => 'Vous n\'êtes pas autorisé à administrer ce serveur.', - 'not_auth_3' => 'Il y avait un problème avec le nom d\'utilisateur ou mot de passe que vous avez entré.', - 'email_format_bad' => 'L\'adresse e-mail que vous avez entré n\'a pas été formaté correctement.', - 'history_header_format' => '
%spar %s
', - 'history_no_history_available_text' => '

Aucune Historique disponible pour cette réuniong

', - 'service_body_editor_disclosure' => 'Administration du composante de structure de service', - 'service_body_change_fader_success_text' => 'Le composante de structure de service a été changé avec succès', - 'service_body_change_fader_fail_text' => 'Le changement du composante de structure de service a échoué', - 'service_body_editor_screen_sb_id_label' => 'ID:', - 'service_body_editor_screen_sb_name_label' => 'Nom:', - 'service_body_name_default_prompt_text' => 'Entrer le nom de ce composante de structure de service', - 'service_body_parent_popup_label' => 'composante de structure de service parent:', - 'service_body_parent_popup_no_parent_option' => 'Aucun Parent (Top-Niveau)', - 'service_body_editor_screen_sb_admin_user_label' => 'Administrateur principal:', - 'service_body_editor_screen_sb_admin_description_label' => 'Description:', - 'service_body_description_default_prompt_text' => 'Entrer une description de ce composante de structure de service', - 'service_body_editor_screen_sb_admin_email_label' => 'Contact E-mail:', - 'service_body_email_default_prompt_text' => 'Entrer un adresse de Contact E-mail pour le composante de structure de service', - 'service_body_editor_screen_sb_admin_uri_label' => 'URL du site Web:', - 'service_body_uri_default_prompt_text' => 'Entrer l\'URL du site Web pour ce composante de structure de service', - 'service_body_editor_screen_sb_admin_full_editor_label' => 'Éditeurs de liste complète de réunions:', - 'service_body_editor_screen_sb_admin_full_editor_desc' => 'Ces utilisateurs peuvent modifier toutes les réunions de ce composante de structure de service.', - 'service_body_editor_screen_sb_admin_editor_label' => 'Éditeurs de base de liste de réunions:', - 'service_body_editor_screen_sb_admin_editor_desc' => 'Ces utilisateurs peuvent modifier toutes les réunions de cet composante de structure de service, mais seulement si elles ne sont pas publiées.', - 'service_body_editor_screen_sb_admin_observer_label' => 'Observateurs:', - 'service_body_editor_screen_sb_admin_observer_desc' => 'Ces utilisateurs peuvent voir des informations cachés (comme les adresses courriel), mais ne peut rien modifier.', - 'service_body_dirty_confirm_text' => 'Vous avez apporté des modifications à cet composante de structure de service. Voulez-vous perdre vos modifications?', - 'service_body_save_button' => 'Sauvegarder les changements de ces composantes de structure de service', - 'service_body_create_button' => 'Créer une composante de structure de service', - 'service_body_delete_button' => 'Supprimer cette composante de structure de service', - 'service_body_delete_perm_checkbox' => 'Supprimer cette composante de structure de service Permanently', - 'service_body_delete_button_confirm' => 'Are you sure that you want to delete this composante de structure de service? Make sure that all meetings are either removed or transferred to another service body before performing this function.', - 'service_body_delete_button_confirm_perm' => 'Cette composante de structure de service sera supprimée de façon permanante!', - 'service_body_change_fader_create_success_text' => 'The composante de structure de service a été créée avec succès', - 'service_body_change_fader_create_fail_text' => 'La création de composante de structure de service a échouée', - 'service_body_change_fader_delete_success_text' => 'La composante de structure de service a été supprimée avec succès', - 'service_body_change_fader_delete_fail_text' => 'La suppression de composante de structure de service a échouée', - 'service_body_change_fader_fail_no_data_text' => 'La modification de la composante de structure de service a échouée, parce que il n\'y avait pas de données fournis', - 'service_body_change_fader_fail_cant_find_sb_text' => 'La modification de la composante de structure de service a échouée, parce que la Composante de la structure de service est introuvable', - 'service_body_change_fader_fail_cant_update_text' => 'La modification de la composante de structure de service a échouée, parce que la Composante de la structure de service n\'a pas été mise à jour', - 'service_body_change_fader_fail_bad_hierarchy' => 'La modification de la composante de structure de service a échouée, parce que le propriétaire de la structure Composante de service sélectionné est sous cette Composante de la structure de service et ne peut être utilisé', - 'service_body_cancel_button' => 'Restaurer l\'original', - 'service_body_editor_type_label' => 'Type de composante de structure de service', - 'service_body_editor_type_c_comdef_service_body__GRP__' => 'Groupe', - 'service_body_editor_type_c_comdef_service_body__COP__' => 'Co-Op', - 'service_body_editor_type_c_comdef_service_body__ASC__' => 'Comité de service local', - 'service_body_editor_type_c_comdef_service_body__RSC__' => 'Comité de Service Regional', - 'service_body_editor_type_c_comdef_service_body__WSC__' => 'Conférence Service mondial', - 'service_body_editor_type_c_comdef_service_body__MAS__' => 'Métro Local', - 'service_body_editor_type_c_comdef_service_body__ZFM__' => 'Forum Zonal', - 'service_body_editor_type_c_comdef_service_body__GSU__' => 'Group Service Unit', - 'service_body_editor_type_c_comdef_service_body__LSU__' => 'Local Service Unit', - 'service_body_editor_screen_helpline_label' => 'Helpline:', - 'service_body_editor_screen_helpline_prompt' => 'Entrer le numéro de téléphone de la Helpline', - 'service_body_editor_uri_naws_format_text' => 'Obtenez les réunions pour cet composante de structure de service de services sous forme de fichier compatible SMNA', - 'edit_Meeting_meeting_id' => 'ID de réunion:', - 'service_body_editor_create_new_sb_option' => 'Créer une nouvelle composante de structure de service', - 'service_body_editor_screen_world_cc_label' => 'Code mondial de comité:', - 'service_body_editor_screen_world_cc_prompt' => 'Entrer un code mondial de Comité', - 'user_editor_disclosure' => 'Utilisateur d\'administration', - 'user_editor_create_new_user_option' => 'Créer un nouvel utilisateur', - 'user_editor_screen_sb_id_label' => 'ID:', - 'user_editor_account_login_label' => 'Login utlisateur:', - 'user_editor_login_default_text' => 'Entrer mon login', - 'user_editor_account_type_label' => 'Je suis un:', - 'user_editor_user_owner_label' => 'Appartient à: ', // TODO translate // Done - 'user_editor_account_type_1' => 'Administrateur du serveur', - 'user_editor_account_type_2' => 'Administrateur de la composante de structure de service ', - 'user_editor_account_type_3' => 'Editeur de la composante de structure de service', - 'user_editor_account_type_5' => 'Observateur de la composante de structure de service', - 'user_editor_account_type_4' => 'Désactiver utilisateur', - 'user_editor_account_name_label' => 'Nom d\'utilisateur:', - 'user_editor_name_default_text' => "Entrez le nom d\'utilisateur", - 'user_editor_account_description_label' => 'Description:', - 'user_editor_description_default_text' => "Entrez la description de l\'utilisateur", - 'user_editor_account_email_label' => 'E-mail:', - 'user_editor_email_default_text' => "Entrez le E-mail de l\'Utilisateur", - 'user_change_fader_success_text' => 'L\'utilisateur a été changé avec succès', - 'user_change_fader_fail_text' => 'Le changement de l\'utilisateur a échoué', - 'user_change_fader_create_success_text' => 'L\'utilisateur a été créé avec succès', - 'user_change_fader_create_fail_text' => 'Échec de création de l\'utilisateur', - 'user_change_fader_create_fail_already_exists' => 'Une connexion de l\'utilisateur que vous essayez de créer existe déjà.', - 'user_change_fader_delete_success_text' => 'L\'utilisateur a été supprimé avec succès', - 'user_change_fader_delete_fail_text' => 'Échec de suppression de l\'utilisateur', - 'user_save_button' => 'Enregistrez les modifications à cet utilisateur', - 'user_create_button' => 'Créer ce nouvel utilisateur', - 'user_cancel_button' => 'Restaurer la modification', - 'user_delete_button' => 'Supprimer cet utilisateur', - 'user_delete_perm_checkbox' => 'Supprimer cet utilisateur de façon permanente', - 'user_password_label' => 'Changer mot de passe pour:', - 'user_new_password_label' => 'Définir mot de passe à:', - 'user_password_default_text' => 'Ne rien changer, sauf si vous voulez changer le mot de passe', - 'user_new_password_default_text' => 'Vous devez entrer un mot de passe d\'un nouvel utilisateur', - 'user_dirty_confirm_text' => 'Vous avez apporté des modifications à l\'utilisateur. Voulez-vous perdre vos modifications?', - 'user_delete_button_confirm' => 'Etes-vous sûr que vous voulez supprimer cet utilisateur?', - 'user_delete_button_confirm_perm' => 'Cet utilisateur sera définitivement supprimé!', - 'user_create_password_alert_text' => 'Les nouveaux utilisateurs doivent avoir un mot de passe. Vous n\'avez pas fourni un mot de passe pour cet utilisateur.', - 'user_change_fader_fail_no_data_text' => 'Échec de suppression de l\'utilisateur, parce que il n\'y avait pas de données fournis', - 'user_change_fader_fail_cant_find_sb_text' => 'Échec de suppression de l\'utilisateur, parce que l\'utilisateur n\'a pas été trouvé', - 'user_change_fader_fail_cant_update_text' => 'Échec de suppression de l\'utilisateur, parce que l\'utilisateur n\'a pas été mise à jour', - 'format_editor_disclosure' => 'Administration de format', - 'format_change_fader_change_success_text' => 'Le format a été changé avec succès', - 'format_change_fader_change_fail_text' => 'Le Changement de format a échoué', - 'format_change_fader_create_success_text' => 'Le format a été créé avec succès', - 'format_change_fader_create_fail_text' => 'La création du format a échoué', - 'format_change_fader_delete_success_text' => 'Le format a été supprimé avec succès', - 'format_change_fader_delete_fail_text' => 'La suppréssion du format a échoué', - 'format_change_fader_fail_no_data_text' => 'Le changement du format a échoué, parce que il n\'y avait pas de données fournis', - 'format_change_fader_fail_cant_find_sb_text' => 'Le changement du format a échoué, parce que le format n\'a pas été trouvé', - 'format_change_fader_fail_cant_update_text' => 'Le changement du format a échoué, parce que le format n\'a pas été mise à jour', - 'format_editor_name_default_text' => 'Entrez une description très courte', - 'format_editor_description_default_text' => 'Entrez une description plus détaillée', - 'format_editor_create_format_button_text' => 'Créer un nouveau format', - 'format_editor_cancel_create_format_button_text' => 'Annuler', - 'format_editor_create_this_format_button_text' => 'Créer ce format', - 'format_editor_change_format_button_text' => 'Modifier ce format', - 'format_editor_delete_format_button_text' => 'Supprimer ce format', - 'format_editor_reset_format_button_text' => 'Restaurer la modification', - 'need_refresh_message_fader_text' => 'Vous devez actualiser cette page avant d\'utiliser cette section', - 'need_refresh_message_alert_text' => 'Parce que vous avez fait des changements dd l\'administration de la structure de composante de service, gestion des utilisateurs ou d\'administration de format, les informations affichées dans cette section peuvent ne plus être exactes même si la page doit être rafraîchie. La meilleure façon de le faire est de vous déconnecter, puis vous connecter à nouveau.', - 'format_editor_delete_button_confirm' => 'Etes-vous sûr que vous voulez supprimer ce format?', - 'format_editor_delete_button_confirm_perm' => 'Ce format sera définitivement supprimé!', - 'format_editor_reserved_key' => 'Cette clé est réservée à un format de type "lieu" - veuillez utiliser quelque chose de différent.', - 'min_password_length_string' => 'Le mot de passe est trop court! Il doit être au moins contenir au moins %d caractères!', - 'AJAX_Auth_Failure' => 'Échec de l\'autorisation pour cette opération. Il peut y avoir un problème avec la configuration du serveur.', - 'Maps_API_Key_Warning' => 'Il y a un problème avec API Key Google maps.', - 'Observer_Link_Text' => 'Navigateur pour les réunions', - 'Data_Transfer_Link_Text' => 'Import Meeting Data (WARNING: Replaces Current Data!)', - 'MapsURL' => 'https://maps.google.com/maps?q=##LAT##,##LONG##+(##NAME##)&ll=##LAT##,##LONG##', - 'hidden_value' => 'Cannot Display Data -Unauthorized', - 'Value_Prompts' => array( - 'id_bigint' => 'ID de Réuniom', - 'worldid_mixed' => 'ID de Services Mondiaux', - 'service_body' => 'Composante de structure de service', - 'service_bodies' => 'Composantes de structure de service', - 'weekdays' => 'Jours de la semaine', - 'weekday' => 'Cette réunion a lieu à tous les', - 'start_time' => 'Laréunion débute à', - 'duration_time' => 'La réunion dure', - 'location' => 'Ville', - 'duration_time_hour' => 'Heure', - 'duration_time_hours' => 'Heures', - 'duration_time_minute' => 'Minute', - 'duration_time_minutes' => 'Minutes', - 'lang_enum' => 'Language', - 'formats' => 'Formats', - 'distance' => 'Distance du Centre', - 'generic' => 'Réunion NA', - 'close_title' => 'Fermez cette fenêtre Détail de Réunion', - 'close_text' => 'Fermer la fenêtre', - 'map_alt' => 'Carte de la réunion', - 'map' => 'Suivez ce lien pour la carte', - 'title_checkbox_unpub_meeting' => 'Cette rencontre n\'est pas publiée. Il ne peut pas être vu par des recherches régulières.', - 'title_checkbox_copy_meeting' => 'Cette réunion est une copie d\'une autre réunion. Il est également non publié. Elle ne peut être vue par recherches régulières.' - ), - 'world_format_codes_prompt' => 'Format SMNA:', - 'world_format_codes' => array( - '' => 'Aucun', - 'OPEN' => 'Ouvert', - 'CLOSED' => 'Fermée', - 'WCHR' => 'Fauteuil Roulant', - 'BEG' => 'Débutant/Nouveau', - 'BT' => 'Texte de base', - 'CAN' => 'À la Chandelle', - 'CPT' => '12 Concepts', - 'CW' => 'Enfants bienvenus', - 'DISC' => 'Discussion', - 'GL' => 'Gays/Lesbiennes', - 'IP' => 'Étude de pamphlet IP', - 'IW' => 'Étude du livre « Ça marche »', - 'JFT' => 'Étude du livre « Juste pour aujourd’hui »', - 'LC' => 'Étude du livre « Vivre abstinent »', - 'LIT' => 'Étude de littérature', - 'M' => 'Hommes', - 'MED' => 'Méditation', - 'NS' => 'Non-Smoking', - 'QA' => 'Questions et réponses', - 'RA' => 'Accès limité', - 'S-D' => 'Speaker/Discussion', // Same in french - 'SMOK' => 'Fumeurs', - 'SPK' => 'Partage', - 'STEP' => 'Étapes', - 'SWG' => 'Étude du « Guide de travail sur les étapes »', - 'TOP' => 'Thématique', - 'TRAD' => 'Traditions', - 'VAR' => 'Formats variés', - 'W' => 'Femmes', - 'Y' => 'Jeunes', - 'LANG' => 'Langue étrangère', - 'GP' => 'Principes de base', - 'NC' => 'Pas d\'enfants', - 'CH' => 'Fermé pour les vacances', - 'VM' => 'virtuelle', - 'HYBR' => 'virtuelle et physique', - 'TC' => 'Temporairement fermée', - 'SPAD' => 'Spiritual Principle a Day', // TODO translate - ), - 'format_type_prompt' => 'Format Type:', - 'format_type_codes' => array( - '' => 'Aucun', - 'FC1' => 'Format de la réunion (Speaker, Étude de la littérature, etc.)', - 'FC2' => 'Code d\'emplacement (Accessible en fauteuil roulant, Parking limité, etc.)', - 'FC3' => 'Common Needs and Restrictions (Réunion hommes, LGBTQI+, Pas d\'enfants, etc.)', - 'O' => 'Présence de non-dépendants (Ouvert, Fermé)', - 'LANG' => 'Langue', - 'ALERT' => 'Le format doit être particulièrement mis en évidence (Nécéssité d\'être clean, etc.)', - ), - 'cookie_monster' => 'Ce site contient un cookie pour emmagasiner l\'information de votre langue de préférée.', - 'main_prompts' => array( - 'id_bigint' => 'ID', - 'worldid_mixed' => 'World ID', - 'shared_group_id_bigint' => 'Unused', - 'service_body_bigint' => 'Service Body ID', - 'weekday_tinyint' => 'Weekday', - 'venue_type' => 'Venue Type', - 'start_time' => 'Start Time', - 'duration_time' => 'Duration', - 'time_zone' => 'Time Zone', - 'formats' => 'Formats', - 'lang_enum' => 'Language', - 'longitude' => 'Longitude', - 'latitude' => 'Latitude', - 'published' => 'Published', - 'email_contact' => 'Email Contact', - ), - 'check_all' => 'Tout cocher', - 'uncheck_all' => 'Tout décocher', - 'automatically_calculated_on_save' => 'Calculé automatiquement lors de la sauvegarde.' -); - -$email_contact_strings = array( - 'meeting_contact_form_subject_format' => "[MEETING LIST CONTACT] %s", - 'meeting_contact_message_format' => "%s\n--\nThis message concerns the meeting named \"%s\", which meets at %s, on %s.\nBrowser Link: %s\nEdit Link: %s\nIt was sent directly from the meeting list web server, and the sender is not aware of your email address.\nPlease be aware that replying will expose your email address.\nIf you use \"Reply All\", and there are multiple email recipients, you may expose other people's email addresses.\nPlease respect people's privacy and anonymity; including the original sender of this message." -); - -$change_type_strings = array( - '__THE_MEETING_WAS_CHANGED__' => 'La réunion a été changé.', - '__THE_MEETING_WAS_CREATED__' => 'La réunion a été créé.', - '__THE_MEETING_WAS_DELETED__' => 'La réunion a été supprimée.', - '__THE_MEETING_WAS_ROLLED_BACK__' => 'La réunion a été restaurée pour une version précédente.', - - '__THE_FORMAT_WAS_CHANGED__' => 'Le format a été changé.', - '__THE_FORMAT_WAS_CREATED__' => 'Le format a été créé.', - '__THE_FORMAT_WAS_DELETED__' => 'Le format a été supprimé.', - '__THE_FORMAT_WAS_ROLLED_BACK__' => 'Le format a été restauré pour une version précédente.', - - '__THE_SERVICE_BODY_WAS_CHANGED__' => 'La composante de structure de service a été modifiée.', - '__THE_SERVICE_BODY_WAS_CREATED__' => 'La composante de structure a été créée.', - '__THE_SERVICE_BODY_WAS_DELETED__' => 'La composante de structure a été supprimée.', - '__THE_SERVICE_BODY_WAS_ROLLED_BACK__' => 'La composante de structure a été restaurée pour une version précédente.', - - '__THE_USER_WAS_CHANGED__' => 'L\'Utilisateur a été changé.', - '__THE_USER_WAS_CREATED__' => 'L\'Utilisateur a été créé.', - '__THE_USER_WAS_DELETED__' => 'L\'Utilisateur a été supprimé.', - '__THE_USER_WAS_ROLLED_BACK__' => 'L\'Utilisateur a été restauré pour une version précédente.', - - '__BY__' => 'par', - '__FOR__' => 'pour' -); - -$detailed_change_strings = array( - 'was_changed_from' => 'a été modifié à partir de', - 'to' => 'à', - 'was_changed' => 'a été changé', - 'was_added_as' => 'a été ajouté en tant que', - 'was_deleted' => 'a été supprimée', - 'was_published' => 'La réunion a été publiée', - 'was_unpublished' => 'La réunion n\'a pas été publiée', - 'formats_prompt' => 'Le format de la réunion', - 'duration_time' => 'La durée de la réunion', - 'start_time' => 'Début de la réuniob', - 'longitude' => 'Longitude de la réunion', - 'latitude' => 'Latitude de la réunion', - 'sb_prompt' => 'La réunion a changé sa composante de structure de service de', - 'id_bigint' => 'ID de réunion', - 'lang_enum' => 'Langue de réunion', - 'worldid_mixed' => 'ID mondial du groupe', // TODO: translate The World Committee Code // Done - 'weekday_tinyint' => 'Le jour de la semaine où la réunion se rassemble', - 'non_existent_service_body' => 'La composante de structure de service n\'existe plus', -); - -defined('_END_CHANGE_REPORT') or define('_END_CHANGE_REPORT', '.'); diff --git a/src/legacy/local_server/server_admin/lang/index.htm b/src/legacy/local_server/server_admin/lang/index.htm deleted file mode 100755 index e69de29bb..000000000 diff --git a/src/legacy/local_server/server_admin/lang/it/data_transfer_strings.php b/src/legacy/local_server/server_admin/lang/it/data_transfer_strings.php deleted file mode 100755 index 624c60e08..000000000 --- a/src/legacy/local_server/server_admin/lang/it/data_transfer_strings.php +++ /dev/null @@ -1,45 +0,0 @@ -.*/ - defined('BMLT_EXEC') or die('Cannot Execute Directly'); // Makes sure that this file is in the correct context. - - $comdef_data_transfer_strings = array ( 'key_strings' => array ( 'id_bigint' => 1, - 'worldid_mixed' => 1, - 'shared_group_id_bigint' => 1, - 'service_body_bigint' => 1, - 'weekday_tinyint' => 1, - 'start_time' => 1, - 'duration_time' => 1, - 'formats' => 1, - 'lang_enum' => 1, - 'longitude' => 1, - 'latitude' => 1, - 'published' => 1, - 'email_contact' => 1 - ), - - 'days' => array ( 'Sunday', - 'Monday', - 'Tuesday', - 'Wednesday', - 'Thursday', - 'Friday', - 'Saturday' - ), - ); diff --git a/src/legacy/local_server/server_admin/lang/it/install_wizard_strings.php b/src/legacy/local_server/server_admin/lang/it/install_wizard_strings.php deleted file mode 100755 index 4c0bf128f..000000000 --- a/src/legacy/local_server/server_admin/lang/it/install_wizard_strings.php +++ /dev/null @@ -1,138 +0,0 @@ -.*/ - defined('BMLT_EXEC') or die('Cannot Execute Directly'); // Makes sure that this file is in the correct context. - - global $comdef_install_wizard_strings; - - $comdef_install_wizard_strings = array ( - 'Database_Version_Error' => 'ERROR: You must have PHP Version 5.6 or greater installed on this server!', - 'Database_PDO_Error' => 'ERROR: You do not have PHP PDO installed!', - 'Database_Type_Error' => 'ERROR: Even though you have PDO, you have no database drivers installed!', - 'Database_TestButton_Text' => 'TEST', - 'Database_TestButton_Success' => 'The database connection was successful.', - 'Database_TestButton_Fail' => 'The database connection failed: ', - 'Database_TestButton_Fail2' => 'The database connection failed because there is already an initialized database.', - 'Database_Whitespace_Note' => 'Warning: %s has whitespace at the beginning or end.', - - 'AJAX_Handler_DB_Connect_Error' => 'The database connection failed! Please make sure that the database exists, IS COMPLETELY EMPTY, the user is created, and that user has full permissions on the empty database.', - 'AJAX_Handler_DB_Established_Error' => 'The database already exists, and has been set up! You cannot use this setup to overwrite an existing database!', - 'AJAX_Handler_DB_Incomplete_Error' => 'There is not enough information to initialize the database!', - - 'NoDatabase_Note_AlreadySet' => 'The database has already been initialized with the provided table prefix. Please choose a new one.', - 'NoDatabase_Note_PasswordIssue' => 'You must choose a username and password for the Server Administrator user.', - 'NoServerAdmin_Note_AlreadySet' => 'There is already an existing database, so you cannot set up a Server Administrator account (One already exists).', - 'NeedLongerPasswordNote' => 'This password is too short. It must be at least %d characters long.', - - 'Prev_Button' => 'PREVIOUS', - 'Next_Button' => 'NEXT', - - 'Page_1_Tab' => 'STEP 1: Database', - 'Page_1_Heading' => 'Database Connection Settings', - 'Page_1_Text' => 'Before you can apply the settings on this page, you must set up a new COMPLETELY EMPTY database, and create a database user that has full user rights on that database.', - - 'Database_Name' => 'Database Name:', - 'Database_Name_Default_Text' => 'Enter A Database Name', - 'Database_Type' => 'Database Type:', - 'Database_Host' => 'Database Host:', - 'Database_Host_Default_Text' => 'Enter A Database Host', - 'Database_Host_Additional_Text' => 'This is usually "localhost."', - 'Table_Prefix' => 'Table Prefix:', - 'Table_Prefix_Default_Text' => 'Enter A Table Prefix', - 'Table_Prefix_Additional_Text' => 'Only for multiple root servers sharing a database.', - 'Database_User' => 'Database User:', - 'Database_User_Default_Text' => 'Enter A Database User Name', - 'Database_PW' => 'Database Password:', - 'Database_PW_Default_Text' => 'Enter A Database Password', - 'Database_PW_Additional_Text' => 'Make this an ugly, difficult password. It has a great deal of power, and you will never need to remember it.', - - 'Maps_API_Key_Warning' => 'There is a problem with the Google Maps API Key.', - - 'Page_2_Tab' => 'STEP 2: Google Maps API', - 'Page_2_Heading' => 'Set The Initial Location For Meetings', - 'Page_2_Text' => 'When saving a meeting, the BMLT Root Server uses the Google Maps API to determine the latitude and longitude for the meeting address. These settings are required to allow the BMLT Root Server to communicate with the Google Maps API.', - - 'Page_3_Tab' => 'STEP 3: Server Settings', - 'Page_3_Heading' => 'Set Various Global Server Settings', - 'Page_3_Text' => 'These are a few settings that affect the administration and general configuration of this server. Most server settings are done in the server itself.', - 'Admin_Login' => 'Server Administrator Login:', - 'Admin_Login_Default_Text' => 'Enter A Server Administrator Login', - 'Admin_Login_Additional_Text' => 'This is the login string for the Server Administrator.', - 'Admin_Password' => 'Server Administrator Password:', - 'Admin_Password_Default_Text' => 'Enter A Server Administrator Password', - 'Admin_Password_Additional_Text' => 'Make sure that this is a non-trivial password! It has a great deal of power! (Also, don\'t forget it).', - 'ServerAdminName' => 'Server Administrator', - 'ServerAdminDesc' => 'Main Server Administrator', - 'ServerLangLabel' => 'Default Server Language:', - 'DistanceUnitsLabel' => 'Distance Units:', - 'DistanceUnitsMiles' => 'Miles', - 'DistanceUnitsKM' => 'Kilometres', - 'SearchDepthLabel' => 'Density of Meetings For Automatic Search:', - 'SearchDepthText' => 'This is an approximation of how many meetings need to be found in the automatic radius selection. More meetings means a bigger radius.', - 'HistoryDepthLabel' => 'How Many Meeting Changes To Save:', - 'HistoryDepthText' => 'The longer the history, the larger the database will become.', - 'TitleTextLabel' => 'The Title Of The Administration Screen:', - 'TitleTextDefaultText' => 'Enter A Short Title For the Editing Login Page', - 'BannerTextLabel' => 'Prompt For Administration Login:', - 'BannerTextDefaultText' => 'Enter A Short Prompt For The Login Page', - 'RegionBiasLabel' => 'Region Bias:', - 'PasswordLengthLabel' => 'Minimum Password Length:', - 'PasswordLengthExtraText' => 'This will also affect the Server Administrator password, above.', - 'DurationLabel' => 'Default Meeting Duration:', - 'DurationHourLabel' => 'Hours', - 'DurationMinutesLabel' => 'Minutes', - 'LanguageSelectorEnableLabel' => 'Display Language Selector On Login:', - 'LanguageSelectorEnableExtraText' => 'If you select this, a popup menu will appear in the login screen, so administrators can select their language.', - 'EmailContactEnableLabel' => 'Allow Email Contacts From Meetings:', - 'EmailContactEnableExtraText' => 'If you select this, site visitors will be able to send emails from meeting records.', - - 'Page_4_Tab' => 'STEP 4: Save The Settings', - 'Page_4_Heading' => 'Create the Settings File', - 'Page_4_Text' => 'The root server was unable to create the settings file for you. Instead, we ask you to create it yourself, via FTP or a control panel file manager, name it "auto-config.inc.php", and paste the following text into the file:', - - 'DefaultPasswordLength' => 10, - 'DefaultMeetingCount' => 10, - 'DefaultChangeDepth' => 5, - 'DefaultDistanceUnits' => 'mi', - 'DefaultDurationTime' => '01:30:00', - 'DurationTextInitialText' => 'N.A. Meetings are usually 90 minutes long (an hour and a half), unless otherwise indicated.', - 'time_format' => 'g:i A', - 'change_date_format' => 'g:i A, n/j/Y', - 'BannerTextInitialText' => 'Administration Login', - 'TitleTextInitialText' => 'Basic Meeting List Toolbox Administration', - 'DefaultRegionBias' => 'us', - 'search_spec_map_center' => array ( 'longitude' => -118.563659, 'latitude' => 34.235918, 'zoom' => 6 ), - 'DistanceChoices' => array ( 2, 5, 10, 20, 50 ), - 'HistoryChoices' => array ( 1, 2, 3, 5, 8, 10, 15 ), - 'PW_LengthChices' => array ( 6, 8, 10, 12, 16 ), - 'ServerAdminDefaultLogin' => 'serveradmin', - - 'Explanatory_Text_1_Initial_Intro' => 'This install wizard will guide you through the process of creating an initial database, as well as a configuration file. In the final step, we will create a settings file, and initialize an empty database.', - 'Explanatory_Text_1_DB_Intro' => 'The first thing that you need to do, is create a new, EMPTY database, and a database user that has full access to that database. This is usually done via your Web site Control Panel. Once you have created the database, you need to enter the information about that database into the text items on this page.', - - 'Explanatory_Text_2_Region_Bias_Intro' => 'The "Region Bias" is a code that is sent to Google when a location search is done, and can help Google to make sense of ambiguous search queries.', - - 'Explanatory_Text_3_Server_Admin_Intro' => 'The Server Administrator is the main user for the server. It is the only account that can create new users and Service bodies, and is very powerful. You should create a login ID and a non-trivial password for this account. You\'ll be able to modify the other aspects of the account on the main server, once the database has been set up.', - 'Explanatory_Text_3_Misc_Intro' => 'These are various settings that affect how the root server behaves and appears.', - - 'Explanatory_Text_4_Main_Intro' => 'If you have entered the database information, provided a valid Google Maps API Key, and specified the login information for the Server Administrator, then you can initialize the root server here. Remember that the database must be COMPLETELY EMPTY of BMLT Root Server tables for this server (It can have tables for other servers or services).', - 'Explanatory_Text_4_NAWS_Export' => 'Optionally, you can import the meetings from a NAWS export spreadsheet. Uncheck the box to initialize them to \'unpublished\'. (This is useful if many of the new meetings will need to be edited or deleted, and you don\'t want them showing up in the meantime.)', - 'Explanatory_Text_4_File_Intro' => 'The text in the box below is the PHP source code for the main settings file. You will need to create a file on the server with this text in it. The file is at the same level as the main server directory for the root server.', - 'Explanatory_Text_4_File_Extra' => 'You also need to make sure that the file permissions are restricted (chmod 0644). This prevents the file from being written, and the root server will not run unless the file has the correct permissions.', - 'Page_4_PathInfo' => 'The file needs to be placed as %s/auto-config.inc.php, which is where your %s directory is. After the file has been created and you have put the above text into it, you should execute the following command to make sure that the permissions are correct:', - 'Page_4_Final' => 'Once all this is complete, refresh this page, and you should see the root server login page.', - 'FormatLangNamesLabel' => 'Enter extra languages in format code1:name1 (example "fa:farsi ru:russian"):', - ); diff --git a/src/legacy/local_server/server_admin/lang/it/name.txt b/src/legacy/local_server/server_admin/lang/it/name.txt deleted file mode 100755 index c90c67343..000000000 --- a/src/legacy/local_server/server_admin/lang/it/name.txt +++ /dev/null @@ -1 +0,0 @@ -Italiano \ No newline at end of file diff --git a/src/legacy/local_server/server_admin/lang/it/server_admin_strings.inc.php b/src/legacy/local_server/server_admin/lang/it/server_admin_strings.inc.php deleted file mode 100644 index 1fccdd298..000000000 --- a/src/legacy/local_server/server_admin/lang/it/server_admin_strings.inc.php +++ /dev/null @@ -1,488 +0,0 @@ -. */ - -defined('BMLT_EXEC') or die('Cannot Execute Directly'); // Makes sure that this file is in the correct context. - -$comdef_server_admin_strings = array( - 'server_admin_disclosure' => 'Server Administration', - 'server_admin_naws_spreadsheet_label' => 'Updated World Committee Codes Spreadsheet', - 'update_world_ids_button_text' => 'Update World Committee Codes', - 'update_world_ids_from_spreadsheet_dropdown_text' => 'Update World Committee Codes (Group IDs from NAWS) from NAWS Spreadsheet', - 'server_admin_error_no_world_ids_updated' => 'No World IDs were updated. This could be because your user does not have permission to update the submitted meetings.', - 'server_admin_error_required_spreadsheet_column' => 'Required column does not exist in the spreadsheet: ', - 'server_admin_error_bmlt_id_not_integer' => 'The provided bmlt_id is not an integer: ', - 'server_admin_error_could_not_create_reader' => 'Could not create reader for file: ', - 'server_admin_error_no_files_uploaded' => 'No files were uploaded.', - 'server_admin_error_service_bodies_already_exist' => 'Service bodies with the following World IDs already exist: ', - 'server_admin_error_meetings_already_exist' => 'Meetings with the following World IDs already exist: ', - 'server_admin_ui_num_meetings_updated' => 'Number of meetings updated: ', - 'server_admin_ui_num_meetings_not_updated' => 'Number of meetings that did not need updating: ', - 'server_admin_ui_warning' => 'WARNING', - 'server_admin_ui_errors' => 'Error(s)', - 'server_admin_ui_deleted_meetings_marked' => 'Number of deleted meetings marked so that they won\'t appear in future NAWS exports: ', - 'server_admin_ui_problem_meetings' => 'meetings were found in the spreadsheet that couldn\'t be updated. Problem meeting IDs: ', - 'server_admin_ui_service_bodies_created' => 'Service bodies created: ', - 'server_admin_ui_meetings_created' => 'Meetings created: ', - 'server_admin_ui_users_created' => 'Users created: ', - 'server_admin_ui_refresh_ui_text' => 'Sign out and then sign in again to see the new service bodies, users, and meetings.', - 'import_service_bodies_and_meetings_button_text' => 'Import Service Bodies and Meetings', - 'import_service_bodies_and_meetings_dropdown_text' => 'Import Service Bodies and Meetings from NAWS Export', - 'server_admin_naws_import_spreadsheet_label' => 'NAWS Import Spreadsheet:', - 'server_admin_naws_import_initially_publish' => 'Initialize imported meetings to \'published\': ', - 'server_admin_naws_import_explanation' => 'Uncheck the box to initialize imported meetings to \'unpublished\'. (This is useful if many of the new meetings will need to be edited or deleted, and you don\'t want them showing up in the meantime.)', - 'account_disclosure' => 'Il mio account',//'My Account', - 'account_name_label' => 'Nome del mio account:',//'My Account Name:', - 'account_login_label' => 'Il mio login:',//'My Login:', - 'account_type_label' => 'Io sono un:',//'I Am A:', - 'account_type_1' => 'Amministratore del server',//'Server Administrator', - 'account_type_2' => 'Amministratore della struttura di servizio',//'Service Body Administrator', - 'ServerMapsURL' => 'https://maps.googleapis.com/maps/api/geocode/xml?address=##SEARCH_STRING##&sensor=false', - 'account_type_4' => 'Patetico perdente che non dovrebbe neanche aver accesso a questa pagina - L\'Autore del software ha miseramente fallito!',//'Pathetic Luser Who Shouldn\'t Even Have Access to This Page -The Author of the Software Pooched it BAD!', - 'account_type_5' => 'Osservatore nella struttura di servizio',//'Service Body Observer', - 'change_password_label' => 'Cambia la mia password in:',//'Change My Password To:', - 'change_password_default_text' => 'Ignoralo se non vuoi cambiare la tua password',//'Leave This Alone If You Don\'t Want To Change Your Password', - 'account_email_label' => 'Il mio indirizzo email:',//'My Email Address:', - 'email_address_default_text' => 'Inserisci un indirizzo email',//'Enter An Email Address', - 'account_description_label' => 'La mia descrizione:',//'My Description:', - 'account_description_default_text' => 'Inserisci una descrizione',//'Enter A Description', - 'account_change_button_text' => 'Modifica le impostazioni del mio account',//'Change My Account Settings', - 'account_change_fader_success_text' => 'Le informazioni dell\'account sono state modificate con successo',//'The Account Information Was Successfully Changed', - 'account_change_fader_failure_text' => 'Le informazioni dell\'account non sono state modificate',//'The Account Information Was Not Changed', - 'meeting_editor_disclosure' => 'Editor delle riunioni',//'Meeting Editor', - 'meeting_editor_already_editing_confirm' => 'Stai modificando un\'altra riunione. Vuoi perdere tutte le modifiche fatte in quella riunione?',//'You are currently editing another meeting. Do you want to lose all changes in that meeting?', - 'meeting_change_fader_success_text' => 'La riunione è stata modificata con successo',//'The Meeting Was Successfully Changed', - 'meeting_change_fader_failure_text' => 'La riunione non è stata modificata',//'The Meeting Was Not Changed', - 'meeting_change_fader_success_delete_text' => 'La riunione è stata cancellata con successo',//'The Meeting Was Successfully Deleted', - 'meeting_change_fader_fail_delete_text' => 'La riunione non è stata cancellata',//'The Meeting Was Not Deleted', - 'meeting_change_fader_success_add_text' => 'La nuova riunione è stata aggiunta con successo',//'The New Meeting Was Successfully Added', - 'meeting_change_fader_fail_add_text' => 'La nuova riunione non è stata aggiunta',//'The New Meeting Was Not Added', - 'meeting_text_input_label' => 'Ricerca testuale:',//'Search For Text:', - 'access_service_body_label' => 'Ho accesso a:',//'I Have Access to:', - 'meeting_text_input_default_text' => 'Inserisci il testo da cercare',//'Enter Some Search Text', - 'meeting_text_location_label' => 'Questa è una località o un codice di avviamento postale',//'This is a Location or PostCode', - 'meeting_search_weekdays_label' => 'Cerca nei giorni selezionati:',//'Search For Selected Weekdays:', - 'meeting_search_weekdays_names' => array('Tutti', 'Domenica', 'Lunedì', 'Martedì', 'Mercoledì', 'Giovedì', 'Venerdì', 'Sabato'),//( 'All', 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday' ), - 'meeting_search_service_bodies_label' => 'Cerca nelle strutture di servizio selezionate:',//'Search In Selected Service Bodies:', - 'meeting_search_start_time_label' => 'Cerca per orario di inizio riunione:',//'Search By Meeting Start Time:', - 'meeting_search_start_time_all_label' => 'In ogni momento',//'Any Time', - 'meeting_search_start_time_morn_label' => 'Mattina',//'Morning', - 'meeting_search_start_time_aft_label' => 'Pomeriggio',//'Afternoon', - 'meeting_search_start_time_eve_label' => 'Sera',//'Evening', - 'meeting_search_no_results_text' => 'Nessuna riunione trovata',//'No Meetings Found', - 'meeting_editor_tab_specifier_text' => 'Cerca per riunione',//'Search For Meetings', - 'meeting_editor_tab_editor_text' => 'Modifica riunione', // TODO: change to 'Edit Or Create Meetings' - 'meeting_editor_create_new_text' => 'Crea una nuova riunione',//'Create A New Meeting', - 'meeting_editor_location_map_link' => 'Mappa delle località',//'Location Map', - 'meeting_editor_screen_match_ll_button' => 'Imposta longitudine e latitudine sull\'indirizzo',//'Set Longitude and Latitude to Address', - 'meeting_editor_screen_default_text_prompt' => 'Inserisci del testo o un numero',//'Enter Some Text or a Number', - 'meeting_is_published' => 'La riunione è pubblicata',//'Meeting is Published', - 'meeting_unpublished_note' => 'Note: Unpublishing a meeting indicates a temporary closure. If this meeting has closed permanently, please delete it.', - 'meeting_editor_screen_meeting_name_label' => 'Nome della riunione:',//'Meeting Name:', - 'meeting_editor_screen_meeting_name_prompt' => 'Inserisci un nome per la riunione',//'Enter A Meeting Name', - 'meeting_editor_screen_meeting_weekday_label' => 'Giorno della settimana:',//'Weekday:', - 'meeting_editor_screen_meeting_start_label' => 'Orario di inizio della riunione:',//'Meeting Start Time:', - 'meeting_editor_screen_meeting_time_zone_label' => 'Meeting Time Zone:',//'Meeting Time Zone:`, - 'meeting_editor_screen_meeting_am_label' => 'AM',//'AM', - 'meeting_editor_screen_meeting_pm_label' => 'PM',//'PM', - 'meeting_editor_screen_meeting_noon_label' => 'Mezzogiorno',//'Noon', - 'meeting_editor_screen_meeting_midnight_label' => 'Mezzanotte',//Midnight', - 'meeting_editor_screen_meeting_duration_label' => 'Durata:',//'Duration:', - 'meeting_editor_screen_meeting_oe_label' => 'Senza orario di fine',//'Open-Ended', - 'meeting_editor_screen_meeting_cc_label' => 'Codice del comitato mondiale:',//'World Committee Code:', - 'meeting_editor_screen_meeting_cc_advice' => 'Normally leave this field alone (see documentation).', // TODO: translate - 'meeting_editor_screen_meeting_contact_label' => 'Contatto email della riunione:',//'Meeting Email Contact:', - 'meeting_editor_screen_meeting_contact_prompt' => 'Inserisci un email di contatto specifica solo per questa riunione',//'Enter An Email for A Contact Specific Only to This Meeting', - 'meeting_editor_screen_meeting_sb_label' => 'Struttura di servizio:',//'Service Body:', - 'meeting_editor_screen_meeting_sb_default_value' => 'Nessuna struttura di servizio selezionata',//'No Service Body Selected', - 'meeting_editor_screen_meeting_longitude_label' => 'Longitudine:',//'Longitude:', - 'meeting_editor_screen_meeting_longitude_prompt' => 'Inserisci una longitudine',//'Enter A Longitude', - 'meeting_editor_screen_meeting_latitude_label' => 'Latitudine:',//'Latitude:', - 'meeting_editor_screen_meeting_latitude_prompt' => 'Inserisci una latitudine',//'Enter A Latitude', - 'meeting_editor_screen_meeting_location_label' => 'Luogo:',//'Location:', - 'meeting_editor_screen_meeting_location_prompt' => 'Inserisci un nome per il luogo della riunione (come il nome dell\'edificio)',//Enter A Location Name (Like a Building Name)',//Enter A Location Name (Like a Building Name)', - 'meeting_editor_screen_meeting_info_label' => 'Informazioni extra:',//'Extra Info:', - 'meeting_editor_screen_meeting_info_prompt' => 'Inserisci ogni altra informazione aggiuntiva sul luogo',//'Enter Any Additional Location Information', - 'meeting_editor_screen_meeting_street_label' => 'Indirizzo:',//'Street Address:', - 'meeting_editor_screen_meeting_street_prompt' => 'Inserisci un indirizzo',//'Enter A Street Address', - 'meeting_editor_screen_meeting_neighborhood_label' => 'Zona, rione:',//'Neighborhood:', - 'meeting_editor_screen_meeting_neighborhood_prompt' => 'Inserisci una zona o un rione (non un quartiere o altro distretto cittadino)',//'Enter A Neighborhood (Not Borough or City Subsection)', - 'meeting_editor_screen_meeting_borough_label' => 'Quartiere/Frazione:',//'Borough/City Subsection:', - 'meeting_editor_screen_meeting_borough_prompt' => 'Inserisci un quartiere o una frazione (non zona o rione)',//'Enter A Borough or City Subsection (Not Neighborhood)', - 'meeting_editor_screen_meeting_city_label' => 'Città:',//'City/Town:', - 'meeting_editor_screen_meeting_city_prompt' => 'Inserisci il nome della città (non di provincia o quartiere)',//'Enter A City or Town Name (Not County or Borough)', - 'meeting_editor_screen_meeting_county_label' => 'Provincia:',//'County/Sub-Province:', - 'meeting_editor_screen_meeting_county_prompt' => 'Inserisci il nome della provincia',//'Enter A County or Sub-Province Name', - 'meeting_editor_screen_meeting_state_label' => 'Regione:',//'State/Province:', - 'meeting_editor_screen_meeting_state_prompt' => 'Inserisci il nome della regione',//'Enter A State or Province Name', - 'meeting_editor_screen_meeting_zip_label' => 'Codice di avviamento postale (CAP):',//'Zip Code/Postal Code:', - 'meeting_editor_screen_meeting_zip_prompt' => 'Inserisci il CAP',//'Enter A Postal Code', - 'meeting_editor_screen_meeting_nation_label' => 'Nazione:',//'Nation:', - 'meeting_editor_screen_meeting_nation_prompt' => 'Inserisci il nome della nazione',//'Enter The Nation Name', - 'meeting_editor_screen_meeting_comments_label' => 'Comments:', - 'meeting_editor_screen_meeting_train_lines_label' => 'Train Lines:', - 'meeting_editor_screen_meeting_bus_lines_label' => 'Bus Lines:', - 'meeting_editor_screen_meeting_phone_meeting_number_label' => 'Phone Meeting Dial-in Number:', - 'meeting_editor_screen_meeting_phone_meeting_number_prompt' => 'Enter the dial-in number for a phone or virtual meeting', - 'meeting_editor_screen_meeting_virtual_meeting_link_label' => 'Virtual Meeting Link:', - 'meeting_editor_screen_meeting_virtual_meeting_link_prompt' => 'Enter the link for a virtual meeting', - 'meeting_editor_screen_meeting_virtual_meeting_additional_info_label' => 'Virtual Meeting Additional Information:', - 'meeting_editor_screen_meeting_virtual_meeting_additional_info_prompt' => 'Enter any additional information for joining the virtual meeting, including directly from the app. For example, if the meeting uses Zoom, "Zoom ID: 456 033 8613, Passcode: 1953" would be appropriate.', - 'meeting_editor_screen_meeting_venue_type' => 'Venue Type:', - 'meeting_editor_screen_meeting_venue_type_inperson' => 'In-Person', - 'meeting_editor_screen_meeting_venue_type_virtual' => 'Virtual', - 'meeting_editor_screen_meeting_venue_type_virtualTC' => 'Virtual (temporarily replacing an in-person)', - 'meeting_editor_screen_meeting_venue_type_hybrid' => 'Hybrid (both in-person and virtual)', - 'meeting_editor_screen_meeting_venue_type_validation' => 'You must select a venue type.', - 'meeting_editor_screen_meeting_virtual_info_missing' => 'Virtual or hybrid meetings must have a Virtual Meeting Link, a Phone Meeting Dial-in Number, or Virtual Meeting Additional Information', - 'meeting_editor_screen_meeting_location_warning' => 'Meeting should have a location (at least a city/town and state/province, or a zip/postal code).', - 'meeting_editor_screen_meeting_address_warning' => 'In-person or hybrid meetings should have a street address.', - 'meeting_editor_screen_meeting_url_validation' => 'Virtual Meeting Link is not a valid URL.', - 'meeting_editor_screen_meeting_url_or_phone_warning' => 'Virtual or hybrid meetings should have either a Virtual Meeting Link or a Phone Meeting Dial-in Number', - 'meeting_editor_screen_meeting_additional_warning' => 'Please also fill in Virtual Meeting Additional Information if there is a Virtual Meeting Link.', - 'meeting_editor_screen_in_person_virtual_info_warning' => 'In-person meetings shouldn\'t have any virtual meeting information.', - 'meeting_editor_screen_meeting_virtual_location_info_warning' => 'Virtual meetings shouldn\'t have a location name or address.', - 'meeting_editor_screen_meeting_validation_warning' => 'There are warnings. Are you sure you want to save anyway? If not, press \'cancel\' and go to the Location tab to see the warnings in place and address them.', - 'meeting_editor_screen_meeting_validation_failed' => 'Unable to save due to input errors. Please go to the Location tab to address them, and then retry saving. Errors: ', - 'meeting_editor_screen_meeting_validation_warnings' => 'Input warnings shown on the Location tab: ', - 'meeting_editor_screen_meeting_contact_name_1_label' => 'Contact 1 Name:', - 'meeting_editor_screen_meeting_contact_email_1_label' => 'Contact 1 Email:', - 'meeting_editor_screen_meeting_contact_phone_1_label' => 'Contact 1 Phone:', - 'meeting_editor_screen_meeting_contact_name_2_label' => 'Contact 2 Name:', - 'meeting_editor_screen_meeting_contact_email_2_label' => 'Contact 2 Email:', - 'meeting_editor_screen_meeting_contact_phone_2_label' => 'Contact 2 Phone:', - 'meeting_editor_screen_meeting_publish_search_prompt' => 'Cerca:',//'Look For:', - 'meeting_editor_screen_meeting_publish_search_pub' => 'Solo riunioni pubblicate',//'Published Meetings Only', - 'meeting_editor_screen_meeting_publish_search_unpub' => 'Solo riunioni non pubblicate',//'Unpublished Meetings Only', - 'meeting_editor_screen_meeting_visibility_advice' => 'Questo non è mai visualizzato nelle normali ricerche delle riunioni.',//'This is never displayed in normal meeting searches.', - 'meeting_editor_screen_meeting_publish_search_all' => 'Tutte le riunioni',//'All Meetings', - 'meeting_editor_screen_meeting_create_button' => 'Crea una nuova riunione',//'Create A New Meeting', - 'meeting_editor_screen_delete_button' => 'Elimina questa riunione',//'Delete This Meeting', - 'meeting_editor_screen_delete_button_confirm' => 'Sei sicuro di voler eliminare questa riunione?',//'Are you sure that you want to delete this meeting?', - 'meeting_editor_screen_cancel_button' => 'Cancella',//'Cancel', - 'logout' => 'Esci',//'Sign Out', - 'meeting_editor_screen_cancel_confirm' => 'Sei sicuro di voler annullare la modifica di questa riunione e perdere tutte le variazioni apportate?',//'Are you sure that you want to cancel editing this meeting, and lose all changes?', - 'meeting_lookup_failed' => 'Ricerca dell\'indirizzo non riuscita.',//'The address lookup failed.', - 'meeting_lookup_failed_not_enough_address_info' => 'Nell\'indirizzo non ci sono elementi sufficienti per fare la ricerca.',//'There is not enough valid address information to do a lookup.', - 'meeting_create_button_name' => 'Salva come nuova riunione',//'Save This As A New Meeting', - 'meeting_saved_as_a_copy' => 'Salva questa riunione come copia (crea una nuova riunione)',//'Save This Meeting As A Copy (Creates A New Meeting)', - 'meeting_save_buttonName' => 'Salva le modifiche a questa riunione',//'Save the Changes to This Meeting', - 'meeting_editor_tab_bar_basic_tab_text' => 'Base',//'Basic', - 'meeting_editor_tab_bar_location_tab_text' => 'Località',//'Location', - 'meeting_editor_tab_bar_format_tab_text' => 'Formato',//'Format', - 'meeting_editor_tab_bar_other_tab_text' => 'Altro',//'Other', - 'meeting_editor_tab_bar_history_tab_text' => 'Cronologia',//'History', - 'meeting_editor_result_count_format' => '%d riunioni trovate',//'%d Meetings Found', - 'meeting_id_label' => 'ID della riunione:',//'Meeting ID:', - 'meeting_editor_default_zoom' => '13',//'13', - 'meeting_editor_default_weekday' => '2',//'2', - 'meeting_editor_default_start_time' => '20:30:00',//'20:30:00', - 'login_banner' => 'Basic Meeting List Toolbox (BMLT)',//'Basic Meeting List Toolbox', - 'login_underbanner' => 'Console di amministrazione del Root Server',//'Root Server Administration Console', - 'login' => 'ID di autenticazione',//'Login ID', - 'password' => 'Password',//'Password', - 'button' => 'Entra',//'Log In', - 'cookie' => 'Devi abilitare i cookie per amministrare questo server.',//'You must enable cookies in order to administer this server.', - 'noscript' => 'Non puoi amministrare questo sito senza JavaScript.',//'You cannot administer this site without JavaScript.', - 'title' => 'Per favore, autenticati per amministrare il server.',//'Please log in to administer the server.', - 'edit_Meeting_object_not_found' => 'ERRORE. La riunione non è stata trovata.',//'ERROR: The meeting was not found.', - 'edit_Meeting_object_not_changed' => 'ERRORE. La riunione non è stata modificata.',//'ERROR: The meeting was not changed.', - 'edit_Meeting_auth_failure' => 'Non sei autorizzato a modificare questa riunione.',//'You are not authorized to edit this meeting.', - 'not_auth_1' => 'NON AUTORIZZATO',//'NOT AUTHORIZED', - 'not_auth_2' => 'Non sei autorizzato ad amministrare questo server.',//'You are not authorized to administer this server.', - 'not_auth_3' => 'C\'è stato un problema con il nome utente o la password che hai inserito.',//'There was a problem with the user name or password that you entered.', - 'email_format_bad' => 'L\'indirizzo email che hai immesso non era formattato correttamente.',//'The email address that you entered was not formatted correctly.', - 'history_header_format' => '
%sda %s
', - 'history_no_history_available_text' => '

Nessuna cronologia disponibile per questa riunione

', /// No History Available For This Meeting - 'service_body_editor_disclosure' => 'Amministrazione della struttura di servizio',//'Service Body Administration', - 'service_body_change_fader_success_text' => 'La struttura di servizio è stata modificata con successo',//'The Service Body Was Successfully Changed', - 'service_body_change_fader_fail_text' => 'Modifica alla struttura di servizio non riuscita',//'The Service Body Change Failed', - 'service_body_editor_screen_sb_id_label' => 'ID:',//'ID:', - 'service_body_editor_screen_sb_name_label' => 'Nome:',//'Name:', - 'service_body_name_default_prompt_text' => 'Inserisci il nome di questa struttura di servizio',//'Enter the Name of This Service Body', - 'service_body_parent_popup_label' => 'Struttura di servizio genitore:',//'Service Body Parent:', - 'service_body_parent_popup_no_parent_option' => 'Nessun genitore (primo livello)',//'No Parent (Top-Level)', - 'service_body_editor_screen_sb_admin_user_label' => 'Amministratore primario:',//'Primary Admin:', - 'service_body_editor_screen_sb_admin_description_label' => 'Descrizione:',//'Description:', - 'service_body_description_default_prompt_text' => 'Inserisci la descrizione di questa struttura di servizio',//'Enter A Description of This Service Body', - 'service_body_editor_screen_sb_admin_email_label' => 'Contatto email:',//'Contact Email:', - 'service_body_email_default_prompt_text' => 'Inserisci il contatto email di questa struttura di servizio',//'Enter A Contact Email Address for This Service Body', - 'service_body_editor_screen_sb_admin_uri_label' => 'Indirizzo (URL) del sito web:',//'Web Site URL:', - 'service_body_uri_default_prompt_text' => 'Inserisci l\'indirizzo (URL) del sito web di questa struttura di servizio',//'Enter A Web Site URL for This Service Body', - 'service_body_editor_screen_sb_admin_full_editor_label' => 'Lista completa delle riunioni:',//'Full Meeting List Editors:', - 'service_body_editor_screen_sb_admin_full_editor_desc' => 'Questi utenti possono modificare tutte le riunioni di questa struttura di servizio.',//'These Users Can Edit Any Meetings In This Service Body.', - 'service_body_editor_screen_sb_admin_editor_label' => 'Editor del BMLT:',//'Basic Meeting List Editors:', - 'service_body_editor_screen_sb_admin_editor_desc' => 'Questi utenti possono modificare tutte le riunioni di questa struttura di servizio, ma solo se non sono ancora state pubblicate.',//'These Users Can Edit Any Meetings In This Service Body, But Only If They Are Unpublished.', - 'service_body_editor_screen_sb_admin_observer_label' => 'Osservatori:',//'Observers:', - 'service_body_editor_screen_sb_admin_observer_desc' => 'Questi utenti possono vedere informazioni nascoste (come gli indirizzi email), ma non possono modificare niente.',//'These Users Can See Hidden Info (Like Email Addresses), But Cannot Edit Anything.', - 'service_body_dirty_confirm_text' => 'Hai fatto delle modifiche a questa struttura di servizio. Vuoi perdere queste variazioni?',//'You have made changes to this Service Body. Do you want to lose your changes?', - 'service_body_save_button' => 'Salva queste modifiche alla struttura di servizio',//'Save These Service Body Changes', - 'service_body_create_button' => 'Crea questa struttura di servizio',//'Create This Service Body', - 'service_body_delete_button' => 'Cancella questa struttura di servizio',//'Delete This Service Body', - 'service_body_delete_perm_checkbox' => 'Cancella definitivamente questa struttura di servizio',//'Delete This Service Body Permanently', - 'service_body_delete_button_confirm' => 'Sei sicuro di voler cancellare questa struttura di servizio? Make sure that all meetings are either removed or transferred to another service body before performing this function.',//'Are you sure that you want to delete this Service body?', - 'service_body_delete_button_confirm_perm' => 'Questa struttura di servizio sarà cancellata definitivamente!',//'This Service body will be deleted permanently!', - 'service_body_change_fader_create_success_text' => 'Struttura di servizio creata con successo',//'The Service Body Was Successfully Created', - 'service_body_change_fader_create_fail_text' => 'Creazione della struttura di servizio non riuscita',//'The Service Body Create Failed', - 'service_body_change_fader_delete_success_text' => 'Struttura di servizio cancellata con successo',//'The Service Body Was Successfully Deleted', - 'service_body_change_fader_delete_fail_text' => 'Creazione della struttura di servizio non riuscita',//'The Service Body Delete Failed', - 'service_body_change_fader_fail_no_data_text' => 'Modifica alla struttura di servizio non riuscita per mancanza di dati',//'The Service Body Change Failed, Because There Was No Data Supplied', - 'service_body_change_fader_fail_cant_find_sb_text' => 'La modifica alla struttura di servizio non è riuscita perché la struttura non è stata trovata',//'The Service Body Change Failed, Because The Service Body Was Not Found', - 'service_body_change_fader_fail_cant_update_text' => 'La modifica alla struttura di servizio non è riuscita perché la struttura non era aggiornata',//'The Service Body Change Failed, Because The Service Body Was Not Updated', - 'service_body_change_fader_fail_bad_hierarchy' => 'La modifica alla struttura di servizio non è riuscita perché il proprietario della struttura di servizio selezionato è sotto questa struttura di servizio e non può essere usato',//'The Service Body Change Failed, Because The Selected Owner Service Body Is Under This Service Body, And Cannot Be Used', - 'service_body_cancel_button' => 'Ripristina l\'originale',//'Restore To Original', - 'service_body_editor_type_label' => 'Tipo di struttura di servizio:',//'Service Body Type:', - 'service_body_editor_type_c_comdef_service_body__GRP__' => 'Gruppo',//'Group', - 'service_body_editor_type_c_comdef_service_body__COP__' => 'Co-Op',//'Co-Op', - 'service_body_editor_type_c_comdef_service_body__ASC__' => 'Comitato di servizio d\'area',//'Area Service Committee', - 'service_body_editor_type_c_comdef_service_body__RSC__' => 'Conferenza dei servizi di regione',//'Regional Service Conference', - 'service_body_editor_type_c_comdef_service_body__WSC__' => 'Conferenza dei servizi mondiali',//'World Service Conference', - 'service_body_editor_type_c_comdef_service_body__MAS__' => 'Area metropolitana',//'Metro Area', - 'service_body_editor_type_c_comdef_service_body__ZFM__' => 'Forum zonale',//'Zonal Forum', - 'service_body_editor_screen_helpline_label' => 'Telefono:', - 'service_body_editor_screen_helpline_prompt' => 'Inserisci il numero di telefono', - 'service_body_editor_uri_naws_format_text' => 'Scarica le riunioni di questa struttura di servizio come file compatibile con i Servizi Mondiali di NA',//'Get The Meetings For This Service Body As A NAWS-Compatible File', - 'edit_Meeting_meeting_id' => 'ID della riunione:',//'Meeting ID:', - 'service_body_editor_create_new_sb_option' => 'Crea una nuova struttura di servizio',//'Create A New Service Body', - 'service_body_editor_screen_world_cc_label' => 'Codice del comitato mondiale:',//'World Committee Code:', - 'service_body_editor_screen_world_cc_prompt' => 'Inserisci un codice per il comitato mondiale',//'Enter A World Committee Code', - 'user_editor_disclosure' => 'Amministrazione dell\'utente',//'User Administration', - 'user_editor_create_new_user_option' => 'Crea un nuovo utente',//'Create A New User', - 'user_editor_screen_sb_id_label' => 'ID:',//'ID:', - 'user_editor_account_login_label' => 'Autenticazione dell\'utente:',//'User Login:', - 'user_editor_login_default_text' => 'Inserisci l\'autenticazione dell\'utente',//'Enter the User Login', - 'user_editor_account_type_label' => 'L\'utente è un:',//'User Is A:', - 'user_editor_user_owner_label' => 'Owned By: ', // TODO translate - 'user_editor_account_type_1' => 'Amministratore del server',//'Server Administrator', - 'user_editor_account_type_2' => 'Amministratore della struttura di servizio',//'Service Body Administrator', - 'user_editor_account_type_3' => 'Editor nella struttura di servizio',//'Service Body Editor', - 'user_editor_account_type_5' => 'Osservatore nella struttura di servizio',//'Service Body Observer', - 'user_editor_account_type_4' => 'Disattiva utente',//'Disabled User', - 'user_editor_account_name_label' => 'Nome utente:',//'User Name:', - 'user_editor_name_default_text' => 'Inserisci il nome utente',//'Enter the User Name', - 'user_editor_account_description_label' => 'Descrizione:',//'Description:', - 'user_editor_description_default_text' => 'Inserisci la descrizione dell\'utente',//'Enter the User Description', - 'user_editor_account_email_label' => 'Email:',//'Email:', - 'user_editor_email_default_text' => ' l\'email dell\'utente',//'Enter the User Email', - 'user_change_fader_success_text' => 'L\'utente è stato modificato con successo',//'The User Was Successfully Changed', - 'user_change_fader_fail_text' => 'La modifica all\'utente è fallita',//'The User Change Failed', - 'user_change_fader_create_success_text' => 'L\'utente è stato creato con successo',//'The User Was Successfully Created', - 'user_change_fader_create_fail_text' => 'La creazione dell\'utente è fallita',//'The User Create Failed', - 'user_change_fader_create_fail_already_exists' => 'Esiste già un profilo per l\'utente che stai cercando di creare.',//'A Login For The User That You Are Trying To Create Already Exists.', - 'user_change_fader_delete_success_text' => 'L\'utente è stato eliminato con successo',//'The User Was Successfully Deleted', - 'user_change_fader_delete_fail_text' => 'L\'eliminazione dell\'utente è fallita',//'The User Delete Failed', - 'user_save_button' => 'Salva le modifiche per questo utente',//'Save the Changes to This User', - 'user_create_button' => 'Crea nuovo utente', - 'user_cancel_button' => 'Ripristina l\'originale', - 'user_delete_button' => 'Cancella questo utente', - 'user_delete_perm_checkbox' => 'Cancella definitivamente questo utente', - 'user_password_label' => 'Cambia password per:', - 'user_new_password_label' => 'Imposta password per:', - 'user_password_default_text' => 'Lascialo così a meno che non voglia cambiare la password', /// 'Leave This Alone, Unless You Want To Change The Password' - 'user_new_password_default_text' => 'Devi inserire un password per il nuovo utente', /// 'You Must Enter A Password For A new User', - 'user_dirty_confirm_text' => 'Hai fatto delle modifiche a questo utente. Vuoi perdere queste modifiche?', /// 'You have made changes to this User. Do you want to lose your changes?', - 'user_delete_button_confirm' => 'Sei sicuro di voler cancellare questo utente?', /// 'Are you sure that you want to delete this user?', - 'user_delete_button_confirm_perm' => 'Questo utente sarà cancellato definitivamente!', /// 'This user will be deleted permanently!', - 'user_create_password_alert_text' => 'I nuovi utenti devono avere una password. Non hai fornito una password per questo utente.', /// 'New users must have a password. You have not supplied a password for this user.', - 'user_change_fader_fail_no_data_text' => 'Modifica utente non riuscita per mancanza di dati', /// 'The User Change Failed, Because There Was No Data Supplied' - 'user_change_fader_fail_cant_find_sb_text' => 'La modifica dell\'utente non è riuscita perché l\'utente non è stato trovato', /// 'The User Change Failed, Because The User Was Not Found' - 'user_change_fader_fail_cant_update_text' => 'La modifica dell\'utente non è riuscita perché l\'utente non era aggiornato', /// 'The User Change Failed, Because The User Was Not Updated' - 'format_editor_disclosure' => 'Formato amministrazione', /// 'Format Administration' - 'format_change_fader_change_success_text' => 'Formato cambiato con successo', /// 'The Format Was Successfully Changed' - 'format_change_fader_change_fail_text' => 'Modifica al formato non riuscita', /// 'The Format Change Failed' - 'format_change_fader_create_success_text' => 'Formato creato con successo', /// 'The Format Was Successfully Created' - 'format_change_fader_create_fail_text' => 'Creazione del formato non riuscita', /// 'The Format Create Failed' - 'format_change_fader_delete_success_text' => 'Il formato è stato cancellato con successo', /// 'The Format Was Successfully Deleted' - 'format_change_fader_delete_fail_text' => 'Cancellazione del formato non riuscita', /// 'The Format Delete Failed' - 'format_change_fader_fail_no_data_text' => 'Modifica del formato non riuscita per mancanza di dati', /// 'The Format Change Failed, Because There Was No Data Supplied' - 'format_change_fader_fail_cant_find_sb_text' => 'La modifica del formato non è riuscita perché il formato non è stato trovato', /// 'The Format Change Failed, Because The Format Was Not Found' - 'format_change_fader_fail_cant_update_text' => 'La modifica del formato non è riuscita perché il formato non era aggiornato', /// 'The Format Change Failed, Because The Format Was Not Updated' - 'format_editor_name_default_text' => 'Inserisci una descrizione molto breve', /// 'Enter A Very Short Description' - 'format_editor_description_default_text' => 'Inserisci una descrizione più dettagliata', /// 'Enter A More Detailed Description' - 'format_editor_create_format_button_text' => 'Crea un nuovo formato', /// 'Create New Format' - 'format_editor_cancel_create_format_button_text' => 'Cancella', /// 'Cancel' - 'format_editor_create_this_format_button_text' => 'Crea questo formato', /// 'Create This Format' - 'format_editor_change_format_button_text' => 'Modifica questo formato', /// 'Change This Format' - 'format_editor_delete_format_button_text' => 'Cancella questo formato', /// 'Delete This Format' - 'format_editor_reset_format_button_text' => 'Ripristina l\'originale', /// 'Restore To Original' - 'need_refresh_message_fader_text' => 'Dovresti aggiornare questa pagina prima di usare questa sezione', /// 'You Should Refresh This Page Before Using This Section' - 'need_refresh_message_alert_text' => 'Siccome hai fatto delle modifiche all\'amministrazione di questa struttura di servizio, di questo utente o di questo formato, le informazioni visualizzate in questa sezione potrebbero non esser più accurate; per questo la pagina deve essere aggiornata. Il modo più facile di farlo è disconnettersi e rifare nuovamente l\'accesso.', /// 'Because you have made changes in the Service Body Administration, User Administration or Format Administration, the information displayed in this section may no longer be accurate, so the page needs to be refreshed. The easiest way to do this, is to Sign Out, then Log In again.' - 'format_editor_delete_button_confirm' => 'Sei sicuro di voler cancellare questo formato?', /// 'Are you sure that you want to delete this format?' - 'format_editor_delete_button_confirm_perm' => 'Questo formato sarà cancellato definitivamente!', /// 'This format will be deleted permanently!' - 'format_editor_missing_key' => 'This format should have an entry for every language (at least a key).', // TODO: translate - 'format_editor_reserved_key' => 'This key is reserved for a venue type format - please use something different.', // TODO: translate - 'min_password_length_string' => 'La password è troppo corta! Deve essere lunga almeno %d caratteri!', /// 'The password is too short! It must be at least %d characters long!' - 'AJAX_Auth_Failure' => 'Autorizzazione fallita per questa operazione. Ci potrebbe essere un problema con la configurazione del server.', /// 'Authorization failed for this operation. There may be a problem with the server configuration.' - 'Maps_API_Key_Warning' => 'There is a problem with the Google Maps API Key.', - 'Observer_Link_Text' => 'Meeting Browser', - 'Data_Transfer_Link_Text' => 'Importazione dati delle riunioni (ATTENZIONE: i dati correnti saranno sostituiti!)', /// 'Import Meeting Data (WARNING: Replaces Current Data!)' - 'MapsURL' => 'https://maps.google.com/maps?q=##LAT##,##LONG##+(##NAME##)&ll=##LAT##,##LONG##', - 'hidden_value' => 'Non è possibile mostrare dati (manca l\'autorizzazione)', /// 'Cannot Display Data -Unauthorized' - 'Value_Prompts' => array( - 'id_bigint' => 'ID riunione', /// 'Meeting ID' - 'worldid_mixed' => 'ID dei Servizi Mondiali di NA', /// 'World Services ID', - 'service_body' => 'Struttura di servizio', /// 'Service Body', - 'service_bodies' => 'Strutture di servizio', /// 'Service Bodies', - 'weekdays' => 'Giorni della settimana', /// 'Weekdays', - 'weekday' => 'La riunione si tiene ogni', /// 'Meeting Gathers Every', - 'start_time' => 'La riunione inizia alle ore', /// 'Meeting Starts at', - 'duration_time' => 'La riunione dura', /// 'Meeting Lasts', - 'location' => 'Località', /// 'Location', - 'duration_time_hour' => 'Ora', /// 'Hour', - 'duration_time_hours' => 'Ore', /// 'Hours', - 'duration_time_minute' => 'Minuto', /// 'Minute', - 'duration_time_minutes' => 'Minuti', /// 'Minutes', - 'lang_enum' => 'Lingua', /// 'Language', - 'formats' => 'Formato', /// 'Formats', - 'distance' => 'Distanza dal centro', /// 'Distance from Center', - 'generic' => 'Riunione NA', /// 'NA Meeting', - 'close_title' => 'Chiudi questa finestra di dettaglio della riunione', /// 'Close This Meeting Detail Window', - 'close_text' => 'Chiudi finestra', /// 'Close Window', - 'map_alt' => 'Mappa della riunione', /// 'Map to Meeting', - 'map' => 'Segui questo link per la mappa', /// 'Follow This Link for A Map', - 'title_checkbox_unpub_meeting' => 'Questa riunione non è pubblicata e non può essere vista nelle normali ricerche.', /// 'This meeting is unpublished. It cannot be seen by regular searches.', - 'title_checkbox_copy_meeting' => 'Questa riunione è il duplicato di un\'altra ed è anche non pubblicata; inoltre, non può essere vista nelle normali ricerche.' /// 'This meeting is a duplicate of another meeting. It is also unpublished. It cannot be seen by regular searches.' - ), - 'world_format_codes_prompt' => 'NAWS Format:', - 'world_format_codes' => array( - '' => 'Nessuno', - 'OPEN' => 'Aperta', - 'CLOSED' => 'Chiusa', - 'WCHR' => 'Accessibile ai disabili', - 'BEG' => 'Principianti/Nuovi venuti', - 'BT' => 'Testo base', - 'CAN' => 'Lume di candela', - 'CPT' => 'Dodici Concetti', - 'CW' => 'Ammessi i bambini', - 'DISC' => 'Discussione/Participazione', - 'GL' => 'Gay/Lesbiche', - 'IP' => 'Studio dei pamphlet', - 'IW' => 'Studio di Funziona: come e perché', - 'JFT' => 'Studio del Solo per oggi', - 'LC' => 'Vivere puliti', - 'LIT' => 'Studio della letteratura', - 'M' => 'Uomini', - 'MED' => 'Meditazione', - 'NS' => 'Non-Smoking', // TODO translate - 'QA' => 'Domande e risposte', - 'RA' => 'Accesso limitato', - 'S-D' => 'Speaker/Discussion', // TODO translate - 'SMOK' => 'Fumatori', - 'SPK' => 'Oratore (sedia)', - 'STEP' => 'Passi', - 'SWG' => 'Studio della Guida al lavoro sui passi', - 'TOP' => 'Argomento', - 'TRAD' => 'Tradizioni', - 'VAR' => 'Formato variabile', - 'W' => 'Donne', - 'Y' => 'Giovani', - 'LANG' => 'Lingue alternate', - 'GP' => 'Guiding Principles', // TODO translate - 'NC' => 'No Children', // TODO translate - 'CH' => 'Closed Holidays', // TODO translate - 'VM' => 'Virtual', // TODO translate - 'HYBR' => 'Virtual and In-Person', // TODO translate - 'TC' => 'Temporarily Closed Facility', // TODO translate - 'SPAD' => 'Spiritual Principle a Day', // TODO translate - ), - 'format_type_prompt' => 'Format Type:', // TODO: Translate - 'format_type_codes' => array( - '' => 'None', // TODO: Translate - 'FC1' => 'Meeting Format (Speaker, Book Study, etc.)', // TODO: Translate - 'FC2' => 'Location Code (Wheelchair Accessible, Limited Parking, etc.)', // TODO: Translate - 'FC3' => 'Common Needs and Restrictions (Mens Meeting, LGTBQ, No Children, etc.)', // TODO: Translate - 'O' => 'Attendance by non-addicts (Open, Closed)', // TODO: Translate - 'LANG' => 'Language', // TRANSLATE - 'ALERT' => 'Format should be especially prominent (Clean requirement, etc.)',// TODO: Translate - ), - 'cookie_monster' => 'Questo sito usa dei cookie per conservare le impostazioni della tua lingua preferita.',//'This site uses a cookie to store your preferred language.', - 'main_prompts' => array( - 'id_bigint' => 'ID',//'ID', - 'worldid_mixed' => 'ID mondiale',//'World ID', - 'shared_group_id_bigint' => 'Inutilizzato',//'Unused', - 'service_body_bigint' => 'ID della struttura di servizio',//'Service Body ID', - 'weekday_tinyint' => 'Giorno della settimana',//'Weekday', - 'venue_type' => 'Venue Type', - 'start_time' => 'Ora d\'inizio',//'Start Time', - 'duration_time' => 'Durata',//'Duration', - 'time_zone' => 'Time Zone', - 'formats' => 'Formati',//Formats', - 'lang_enum' => 'Lingua',//'Language', - 'longitude' => 'Longitudine',//'Longitude', - 'latitude' => 'Latitudine',//'Latitude', - 'published' => 'Pubblicato',//'Published', - 'email_contact' => 'Contatto email',//'Email Contact', - ), - 'check_all' => 'Check All', - 'uncheck_all' => 'Uncheck All', - 'automatically_calculated_on_save' => 'Automatically calculated on save.' -); - -$email_contact_strings = array( - 'meeting_contact_form_subject_format' => "[MEETING LIST CONTACT] %s", - 'meeting_contact_message_format' => "%s\n--\nThis message concerns the meeting named \"%s\", which meets at %s, on %s.\nBrowser Link: %s\nEdit Link: %s\nIt was sent directly from the meeting list web server, and the sender is not aware of your email address.\nPlease be aware that replying will expose your email address.\nIf you use \"Reply All\", and there are multiple email recipients, you may expose other people's email addresses.\nPlease respect people's privacy and anonymity; including the original sender of this message." -); - -$change_type_strings = array( - '__THE_MEETING_WAS_CHANGED__' => 'La riunione è stata modificata.',//'The meeting was changed.', THEN: created, deleted rolled back... - '__THE_MEETING_WAS_CREATED__' => 'La riunione è stata creata.', - '__THE_MEETING_WAS_DELETED__' => 'La riunione è stata cancellata.', - '__THE_MEETING_WAS_ROLLED_BACK__' => 'La riunione è stata riportata a una versione precedente.', - - '__THE_FORMAT_WAS_CHANGED__' => 'Il formato è stato modificato.',//'The format was changed.', THEN: created, deleted rolled back... - '__THE_FORMAT_WAS_CREATED__' => 'Il formato è stato creato.', - '__THE_FORMAT_WAS_DELETED__' => 'Il formato è stato cancellato.', - '__THE_FORMAT_WAS_ROLLED_BACK__' => 'Il formato è stato riportato a una versione precedente.', - - '__THE_SERVICE_BODY_WAS_CHANGED__' => 'La struttura di servizio è stata modificata.',//'The service body was changed.', THEN: created, deleted rolled back... - '__THE_SERVICE_BODY_WAS_CREATED__' => 'La struttura di servizio è stata creata.', - '__THE_SERVICE_BODY_WAS_DELETED__' => 'La struttura di servizio è stata cancellata.', - '__THE_SERVICE_BODY_WAS_ROLLED_BACK__' => 'La struttura di servizio è stata riportata a una versione precedente.', - - '__THE_USER_WAS_CHANGED__' => 'L\'utente è stato modificato.',//'The user was changed.', THEN: created, deleted rolled back... - '__THE_USER_WAS_CREATED__' => 'L\'utente è stato creato.', - '__THE_USER_WAS_DELETED__' => 'L\'utente è stato cancellato.', - '__THE_USER_WAS_ROLLED_BACK__' => 'L\'utente è stato riportato a una versione precedente.', - - '__BY__' => 'da',//'by', - '__FOR__' => 'per'//'for' -); - -$detailed_change_strings = array( - 'was_changed_from' => 'è stato modificato da',//was changed from', - 'to' => 'a',//'to', - 'was_changed' => 'è stato modificato',//'was changed', - 'was_added_as' => 'è stato aggiunto come',//'was added as', - 'was_deleted' => 'è stato cancellato',//'was deleted', - 'was_published' => 'La riunione è stata pubblicata',//'The meeting was published', - 'was_unpublished' => 'La riunione non è più pubblicata',//'The meeting was unpublished', - 'formats_prompt' => 'Il formato della riunione',//'The meeting format', - 'duration_time' => 'La durata della riunione',//'The meeting duration', - 'start_time' => 'L\'ora di inizio della riunione',//'The meeting start time', - 'longitude' => 'La longitudine della riunione', - 'latitude' => 'La latitudine della riunione', - 'sb_prompt' => 'La riunione ha modificato la sua struttura di servizio da',//'The meeting changed its Service Body from', - 'id_bigint' => 'ID della riunione',//'The meeting ID', - 'lang_enum' => 'Lingua della riunione',//'The meeting language', - 'worldid_mixed' => 'ID del gruppo condiviso',//'The World Committee Code', - 'weekday_tinyint' => 'Il giorno della settimana in cui si tiene la riunione',//'The day of the week on which the meeting gathers', - 'non_existent_service_body' => 'La struttura di servizio non esiste più',//'Service Body No Longer Exists', -); - -defined('_END_CHANGE_REPORT') or define('_END_CHANGE_REPORT', '.'); diff --git a/src/legacy/local_server/server_admin/lang/pl/data_transfer_strings.php b/src/legacy/local_server/server_admin/lang/pl/data_transfer_strings.php deleted file mode 100755 index 624c60e08..000000000 --- a/src/legacy/local_server/server_admin/lang/pl/data_transfer_strings.php +++ /dev/null @@ -1,45 +0,0 @@ -.*/ - defined('BMLT_EXEC') or die('Cannot Execute Directly'); // Makes sure that this file is in the correct context. - - $comdef_data_transfer_strings = array ( 'key_strings' => array ( 'id_bigint' => 1, - 'worldid_mixed' => 1, - 'shared_group_id_bigint' => 1, - 'service_body_bigint' => 1, - 'weekday_tinyint' => 1, - 'start_time' => 1, - 'duration_time' => 1, - 'formats' => 1, - 'lang_enum' => 1, - 'longitude' => 1, - 'latitude' => 1, - 'published' => 1, - 'email_contact' => 1 - ), - - 'days' => array ( 'Sunday', - 'Monday', - 'Tuesday', - 'Wednesday', - 'Thursday', - 'Friday', - 'Saturday' - ), - ); diff --git a/src/legacy/local_server/server_admin/lang/pl/install_wizard_strings.php b/src/legacy/local_server/server_admin/lang/pl/install_wizard_strings.php deleted file mode 100755 index 8ca9805bd..000000000 --- a/src/legacy/local_server/server_admin/lang/pl/install_wizard_strings.php +++ /dev/null @@ -1,165 +0,0 @@ -.*/ - defined('BMLT_EXEC') or die('Cannot Execute Directly'); // Makes sure that this file is in the correct context. - - global $comdef_install_wizard_strings; - - $comdef_install_wizard_strings = array ( - 'Database_Version_Error' => 'ERROR: You must have PHP Version 5.6 or greater installed on this server!', - 'Database_PDO_Error' => 'ERROR: You do not have PHP PDO installed!', - 'Database_Type_Error' => 'ERROR: Even though you have PDO, you have no database drivers installed!', - 'Database_Type_MySQL_Error' => 'ERROR: Even though you have PDO and you have database drivers installed, none of the are MySQL (the only supported driver)!', - 'Database_TestButton_Text' => 'TEST', - 'Database_TestButton_Success' => 'The database connection was successful.', - 'Database_TestButton_Fail' => 'The database connection failed: ', - 'Database_TestButton_Fail2' => 'The database connection failed because there is already an initialized database.', - 'Database_Whitespace_Note' => 'Warning: %s has whitespace at the beginning or end.', - - 'AJAX_Handler_DB_Connect_Error' => 'The database connection failed! Please make sure that the database exists, IS COMPLETELY EMPTY, the user is created, and that user has full permissions on the empty database.', - 'AJAX_Handler_DB_Established_Error' => 'The database already exists, and has been set up! You cannot use this setup to overwrite an existing database!', - 'AJAX_Handler_DB_Incomplete_Error' => 'There is not enough information to initialize the database!', - - 'NoDatabase_Note_AlreadySet' => 'The database has already been initialized with the provided table prefix. Please choose a new one.', - 'NoDatabase_Note_GenericError' => 'There is an error connecting to the database. Please check your database settings.', - 'NoDatabase_Note_ClickHere' => 'Click here to go back to the database set up page.', - 'NoDatabase_Note_PasswordIssue' => 'You must choose a username and password for the Server Administrator user.', - 'NoDatabase_Note_ServerSettings_ClickHere' => 'Click here to go back to the server settings page.', - 'NoServerAdmin_Note_AlreadySet' => 'There is already an existing database, so you cannot set up a Server Administrator account (One already exists).', - 'NeedLongerPasswordNote' => 'This password is too short. It must be at least %d characters long.', - - 'Prev_Button' => 'PREVIOUS', - 'Next_Button' => 'NEXT', - - 'Page_1_Tab' => 'STEP 1: Database', - 'Page_1_Heading' => 'Database Connection Settings', - 'Page_1_Text' => 'Before you can apply the settings on this page, you must set up a new COMPLETELY EMPTY database, and create a database user that has full user rights on that database.', - - 'Database_Name' => 'Database Name:', - 'Database_Name_Default_Text' => 'Enter A Database Name', - 'Database_Type' => 'Database Type:', - 'Database_Host' => 'Database Host:', - 'Database_Host_Default_Text' => 'Enter A Database Host', - 'Database_Host_Additional_Text' => 'This is usually "localhost."', - 'Table_Prefix' => 'Table Prefix:', - 'Table_Prefix_Default_Text' => 'Enter A Table Prefix', - 'Table_Prefix_Additional_Text' => 'Only for multiple root servers sharing a database.', - 'Database_User' => 'Database User:', - 'Database_User_Default_Text' => 'Enter A Database User Name', - 'Database_PW' => 'Database Password:', - 'Database_PW_Default_Text' => 'Enter A Database Password', - 'Database_PW_Additional_Text' => 'Make this an ugly, difficult password. It has a great deal of power, and you will never need to remember it.', - - 'Maps_API_Key_Warning' => 'There is a problem with the Google Maps API Key.', - 'Maps_API_Key_Not_Set' => 'The Google Maps API key is not set.', - 'Maps_API_Key_Valid' => 'Google Maps API Key is valid.', - 'Maps_API_Key_ClickHere' => 'Click here to go back to the Google Maps API Key set up page.', - - 'Page_2_Tab' => 'STEP 2: Google Maps API Settings', - 'Page_2_Heading' => 'Google Maps API Settings', - 'Page_2_API_Key_Prompt' => 'Enter the Google API Key for Geocoding:', - 'Page_2_API_Key_Set_Button' => 'TEST KEY', - 'Page_2_API_Key_Not_Set_Prompt' => 'SET API KEY FIRST', - 'Page_2_Text' => 'When saving a meeting, the BMLT Root Server uses the Google Maps API to determine the latitude and longitude for the meeting address. These settings are required to allow the BMLT Root Server to communicate with the Google Maps API.', - - 'Page_3_Tab' => 'STEP 3: Server Settings', - 'Page_3_Heading' => 'Set Various Global Server Settings', - 'Page_3_Text' => 'These are a few settings that affect the administration and general configuration of this server. Most server settings are done in the server itself.', - 'Admin_Login' => 'Server Administrator Login:', - 'Admin_Login_Default_Text' => 'Enter A Server Administrator Login', - 'Admin_Login_Additional_Text' => 'This is the login string for the Server Administrator.', - 'Admin_Password' => 'Server Administrator Password:', - 'Admin_Password_Default_Text' => 'Enter A Server Administrator Password', - 'Admin_Password_Additional_Text' => 'Make sure that this is a non-trivial password! It has a great deal of power! (Also, don\'t forget it).', - 'ServerAdminName' => 'Server Administrator', - 'ServerAdminDesc' => 'Main Server Administrator', - 'ServerLangLabel' => 'Default Server Language:', - 'DistanceUnitsLabel' => 'Distance Units:', - 'DistanceUnitsMiles' => 'Miles', - 'DistanceUnitsKM' => 'Kilometres', - 'SearchDepthLabel' => 'Density of Meetings For Automatic Search:', - 'SearchDepthText' => 'This is an approximation of how many meetings need to be found in the automatic radius selection. More meetings means a bigger radius.', - 'HistoryDepthLabel' => 'How Many Meeting Changes To Save:', - 'HistoryDepthText' => ' The longer the history, the larger the database will become.', - 'TitleTextLabel' => 'The Title Of The Administration Screen:', - 'TitleTextDefaultText' => 'Enter A Short Title For the Editing Login Page', - 'BannerTextLabel' => 'Prompt For Administration Login:', - 'BannerTextDefaultText' => 'Enter A Short Prompt For The Login Page', - 'RegionBiasLabel' => 'Region Bias:', - 'PasswordLengthLabel' => 'Minimum Password Length:', - 'PasswordLengthExtraText' => 'This will also affect the Server Administrator password, above.', - 'DefaultClosedStatus' => 'Meetings Are Considerd "CLOSED" by Default:', - 'DefaultClosedStatusExtraText' => 'This primarily affects the export to NAWS.', - 'DurationLabel' => 'Default Meeting Duration:', - 'DurationHourLabel' => 'Hours', - 'DurationMinutesLabel' => 'Minutes', - 'LanguageSelectorEnableLabel' => 'Display Language Selector On Login:', - 'LanguageSelectorEnableExtraText' => 'If you select this, a popup menu will appear in the login screen, so administrators can select their language.', - 'SemanticAdminLabel' => 'Enable Semantic Administration:', - 'SemanticAdminExtraText' => 'If not checked, then all administration must be done via the Root Server login (No apps).', - 'EmailContactEnableLabel' => 'Allow Email Contacts From Meetings:', - 'EmailContactEnableExtraText' => 'If you select this, site visitors will be able to send emails from meeting records.', - 'EmailContactAdminEnableLabel' => 'Include Service Body Administrator On These Emails:', - 'EmailContactAdminEnableExtraText' => 'Sends copies of these emails to the Service Body Administrator (if they are not the primary recipient).', - 'EmailContactAllAdminEnableLabel' => 'Include All Service Body Administrators On These Emails:', - 'EmailContactAllAdminEnableExtraText' => 'Sends copies of these emails to all of the relevant Service Body Administrators.', - - 'Page_4_Initialize_Root_Server_Heading' => 'Initialize the Root Server', - 'Page_4_Initialize_Root_Server_Text' => 'The button below will initialize the Root Server with an empty database and a Server Administrator user.', - 'Page_4_Initialize_Root_Server_Button' => 'Initialize Root Server', - - 'Page_4_Tab' => 'STEP 4: Save The Settings', - 'Page_4_Heading' => 'Create the Settings File', - 'Page_4_Text' => 'The root server was unable to create the settings file for you. Instead, we ask you to create it yourself, via FTP or a control panel file manager, name it "auto-config.inc.php", and paste the following text into the file:', - - 'NAWS_Export_Spreadsheet_Optional' => 'NAWS Export Spreadsheet (Optional): ', - 'NAWS_Export_Spreadsheet_Initially_Publish' => 'Initialize imported meetings to \'published\': ', - - 'DefaultPasswordLength' => 10, - 'DefaultMeetingCount' => 10, - 'DefaultChangeDepth' => 5, - 'DefaultDistanceUnits' => 'mi', - 'DefaultDurationTime' => '01:30:00', - 'DurationTextInitialText' => 'N.A. Meetings are usually 90 minutes long (an hour and a half), unless otherwise indicated.', - 'time_format' => 'g:i A', - 'change_date_format' => 'g:i A, n/j/Y', - 'BannerTextInitialText' => 'Administration Login', - 'TitleTextInitialText' => 'Basic Meeting List Toolbox Administration', - 'DefaultRegionBias' => 'us', - 'search_spec_map_center' => array ( 'longitude' => -118.563659, 'latitude' => 34.235918, 'zoom' => 6 ), - 'DistanceChoices' => array ( 2, 5, 10, 20, 50 ), - 'HistoryChoices' => array ( 1, 2, 3, 5, 8, 10, 15 ), - 'PW_LengthChices' => array ( 6, 8, 10, 12, 16 ), - 'ServerAdminDefaultLogin' => 'serveradmin', - - 'Explanatory_Text_1_Initial_Intro' => 'This install wizard will guide you through the process of creating an initial database, as well as a configuration file. In the final step, we will create a settings file, and initialize an empty database.', - 'Explanatory_Text_1_DB_Intro' => 'The first thing that you need to do, is create a new, EMPTY database, and a database user that has full access to that database. This is usually done via your Web site Control Panel. Once you have created the database, you need to enter the information about that database into the text items on this page.', - - 'Explanatory_Text_2_Region_Bias_Intro' => 'The "Region Bias" is a code that is sent to Google when a location search is done, and can help Google to make sense of ambiguous search queries.', - 'Explanatory_Text_2_API_key_Intro' => 'The "API Key" is a key that you need to register with Google in order to be able to use their mapping service.', - 'Explanatory_Text_2_API_key_2_Intro' => 'You will need to provide a valid API Key in order to create new meetings in the Root Server.', - - 'Explanatory_Text_3_Server_Admin_Intro' => 'The Server Administrator is the main user for the server. It is the only account that can create new users and Service bodies, and is very powerful. You should create a login ID and a non-trivial password for this account. You\'ll be able to modify the other aspects of the account on the main server, once the database has been set up.', - 'Explanatory_Text_3_Misc_Intro' => 'These are various settings that affect how the root server behaves and appears.', - - 'Explanatory_Text_4_Main_Intro' => 'If you have entered the database information, provided a valid Google Maps API Key, and specified the login information for the Server Administrator, then you can initialize the root server here. Remember that the database must be COMPLETELY EMPTY of BMLT Root Server tables for this server (It can have tables for other servers or services).', - 'Explanatory_Text_4_NAWS_Export' => 'Optionally, you can import the meetings from a NAWS export spreadsheet. Uncheck the box to initialize them to \'unpublished\'. (This is useful if many of the new meetings will need to be edited or deleted, and you don\'t want them showing up in the meantime.)', - 'Explanatory_Text_4_File_Intro' => 'The text in the box below is the PHP source code for the main settings file. You will need to create a file on the server with this text in it. The file is at the same level as the main server directory for the root server.', - 'Explanatory_Text_4_File_Extra' => 'You also need to make sure that the file permissions are restricted (chmod 0644). This prevents the file from being written, and the root server will not run unless the file has the correct permissions.', - 'Page_4_PathInfo' => 'The file needs to be placed as %s/auto-config.inc.php, which is where your %s directory is. After the file has been created and you have put the above text into it, you should execute the following command to make sure that the permissions are correct:', - 'Page_4_Final' => 'Once all this is complete, refresh this page, and you should see the root server login page.', - 'FormatLangNamesLabel' => 'Enter extra languages in format code1:name1 (example "fa:farsi ru:russian"):', - ); diff --git a/src/legacy/local_server/server_admin/lang/pl/name.txt b/src/legacy/local_server/server_admin/lang/pl/name.txt deleted file mode 100755 index 98a292b48..000000000 --- a/src/legacy/local_server/server_admin/lang/pl/name.txt +++ /dev/null @@ -1 +0,0 @@ -Polskie \ No newline at end of file diff --git a/src/legacy/local_server/server_admin/lang/pl/server_admin_strings.inc.php b/src/legacy/local_server/server_admin/lang/pl/server_admin_strings.inc.php deleted file mode 100644 index 1be54fb01..000000000 --- a/src/legacy/local_server/server_admin/lang/pl/server_admin_strings.inc.php +++ /dev/null @@ -1,491 +0,0 @@ -. */ - -defined('BMLT_EXEC') or die('Cannot Execute Directly'); // Makes sure that this file is in the correct context. - -$comdef_server_admin_strings = array( - 'server_admin_disclosure' => 'Administracja serwera', - 'server_admin_naws_spreadsheet_label' => 'Zaktualizowano arkusz światowych ID:', // TODO: was changed to "Updated World Committee Codes Spreadsheet" - 'update_world_ids_button_text' => 'Zaktualizuj ID mityngów światowych z arkusza', // TODO: was changed to "'Update World Committee Codes" - 'update_world_ids_from_spreadsheet_dropdown_text' => 'Update World Committee Codes (Group IDs from NAWS) from NAWS Spreadsheet', - 'server_admin_error_no_world_ids_updated' => 'Nie zaktualizowano światowych ID. Przyczyną może być brak uprawnień na Twoim koncie do aktualizacji przesłanych mityngów.', - 'server_admin_error_required_spreadsheet_column' => 'Wymagana kolumna nie istnieje w arkuszu ', - 'server_admin_error_bmlt_id_not_integer' => 'Dostarczone bmlt_id nie jest liczbą całkowitą: ', - 'server_admin_error_could_not_create_reader' => 'Nie udało się stworzyć readera dla pliku: ', - 'server_admin_error_no_files_uploaded' => 'Nie zuploadowano plików.', - 'server_admin_ui_num_meetings_updated' => 'Liczba zaktualizowanych mityngów: ', - 'server_admin_ui_num_meetings_not_updated' => 'Liczba mityngów nie potrzebujących aktualizacji: ', - 'server_admin_ui_errors' => 'Błędy', - 'server_admin_ui_warning' => 'OSTRZEŻENIE', - 'server_admin_ui_deleted_meetings_marked' => 'Number of deleted meetings marked so that they won\'t appear in future NAWS exports: ', - // TODO: re-translate this string (English version has been updated) - // 'server_admin_ui_problem_meetings' => 'znaleziono mityngi w arkuszu, które nie istnieją w bazie danych. Może się to zdarzyć, gdy mityng jest usunięty lub niepubliczny. ID brakujących mityngów to: ', - 'server_admin_ui_problem_meetings' => 'meetings were found in the spreadsheet that couldn\'t be updated. Problem meeting IDs: ', - 'server_admin_ui_service_bodies_created' => 'Utworzone organy służb: ', - 'server_admin_ui_meetings_created' => 'Utworzone mityngi: ', - 'server_admin_ui_users_created' => 'Utworzeni użytkownicy: ', - 'server_admin_ui_refresh_ui_text' => 'Wyloguj i zaloguj się ponownie by zobaczyć nowe organy służb, użytkowników i mityngi.', - 'import_service_bodies_and_meetings_button_text' => 'Zaimportuj organy służb i mityngi', - 'import_service_bodies_and_meetings_dropdown_text' => 'Zaimportuj organy służb i mityngi z NAWS Export', - 'server_admin_naws_import_spreadsheet_label' => 'Arkusz NAWS Import', - 'server_admin_naws_import_initially_publish' => 'Initialize imported meetings to \'published\': ', - 'server_admin_naws_import_explanation' => 'Uncheck the box to initialize imported meetings to \'unpublished\'. (This is useful if many of the new meetings will need to be edited or deleted, and you don\'t want them showing up in the meantime.)', - 'account_disclosure' => 'Moje konto', - 'account_name_label' => 'Moja nazwa konta:', - 'account_login_label' => 'Mój login:', - 'account_type_label' => 'Jestem:', - 'account_type_1' => 'Administrator serwera', - 'account_type_2' => 'Administrator organu służb', - 'ServerMapsURL' => 'https://maps.googleapis.com/maps/api/geocode/xml?address=##SEARCH_STRING##&sensor=false', - 'account_type_4' => 'Żałosny przegryw, który nie powinien mieć dostępu do tej strony - autor oprogramowania dał ciała!', - 'account_type_5' => 'Obserwator z organu służb', - 'change_password_label' => 'Zmień moje hasło na:', - 'change_password_default_text' => 'Nie ruszaj tego, jeśli nie chcesz zmienić hasła', - 'account_email_label' => 'Mój adres e-mail:', - 'email_address_default_text' => 'Podaj adres e-mail', - 'account_description_label' => 'Mój opis:', - 'account_description_default_text' => 'Podaj opis', - 'account_change_button_text' => 'Zmień ustawienia konta', - 'account_change_fader_success_text' => 'Informacje o koncie pomyślnie zmienione', - 'account_change_fader_failure_text' => 'Informacje o koncie nie zostały zmienione', - 'meeting_editor_disclosure' => 'Edytor mityngu', - 'meeting_editor_already_editing_confirm' => 'Aktualnie edytujesz inny mityng. Czy chcesz utracić wszystkie zmiany w tamtym mityngu?', - 'meeting_change_fader_success_text' => 'Pomyślnie zmieniono mityng', - 'meeting_change_fader_failure_text' => 'Mityng nie został zmieniony', - 'meeting_change_fader_success_delete_text' => 'Pomyślnie usunięto mityng', - 'meeting_change_fader_fail_delete_text' => 'Mityng nie został usunięty', - 'meeting_change_fader_success_add_text' => 'Nowy mityng pomyślnie dodany', - 'meeting_change_fader_fail_add_text' => 'Nowy mityng nie został dodany', - 'meeting_text_input_label' => 'Wyszukaj tekst:', - 'access_service_body_label' => 'Mam dostęp do:', - 'meeting_text_input_default_text' => 'Podaj tekst do wyszukania', - 'meeting_text_location_label' => 'To jest lokalizacja lub kod pocztowy', - 'meeting_search_weekdays_label' => 'Wyszukaj wybrane dni tygodnia:', - 'meeting_search_weekdays_names' => array('Wszystkie', 'Niedziela', 'Poniedziałek', 'Wtorek', 'Środa', 'Czwartek', 'Piątek', 'Sobota'), - 'meeting_search_service_bodies_label' => 'Szukaj w wybranych organach służb:', - 'meeting_search_start_time_label' => 'Szukaj według czasu rozpoczęcia mityngu:', - 'meeting_search_start_time_all_label' => 'Kiedykolwiek', - 'meeting_search_start_time_morn_label' => 'Ranek', - 'meeting_search_start_time_aft_label' => 'Popołudnie', - 'meeting_search_start_time_eve_label' => 'Wieczór', - 'meeting_search_no_results_text' => 'Nie znaleziono mityngów', - 'meeting_editor_tab_specifier_text' => 'Szukaj mityngów', - 'meeting_editor_tab_editor_text' => 'Edytuj mityngi', // TODO: change to 'Edit Or Create Meetings' - 'meeting_editor_create_new_text' => 'Stwórz nowy mityng', - 'meeting_editor_location_map_link' => 'Mapa lokalizacji', - 'meeting_editor_screen_match_ll_button' => 'Ustaw długość i szerokość geograficzną na adres:', - 'meeting_editor_screen_default_text_prompt' => 'Wpisz jakiś tekst lub liczbę', - 'meeting_is_published' => 'Mityng opublikowany', - 'meeting_unpublished_note' => 'Uwaga: Cofnięcie publikacji mityngu sugeruje tymczasowe zamknięcie. Jeśli mityng jest zamknięty na stałe - usuń go.', - 'meeting_editor_screen_meeting_name_label' => 'Nazwa mityngu:', - 'meeting_editor_screen_meeting_name_prompt' => 'Podaj nazwę mityngu', - 'meeting_editor_screen_meeting_weekday_label' => 'Dzień tygodnia:', - 'meeting_editor_screen_meeting_start_label' => 'Czas rozpoczęcia mityngu:', - 'meeting_editor_screen_meeting_time_zone_label' => 'Meeting Time Zone:', - 'meeting_editor_screen_meeting_am_label' => 'AM', - 'meeting_editor_screen_meeting_pm_label' => 'PM', - 'meeting_editor_screen_meeting_noon_label' => 'Południe', - 'meeting_editor_screen_meeting_midnight_label' => 'Północ', - 'meeting_editor_screen_meeting_duration_label' => 'Czas trwania:', - 'meeting_editor_screen_meeting_oe_label' => 'Otwarty', - 'meeting_editor_screen_meeting_cc_label' => 'Kod Komitetu Światowego:', - 'meeting_editor_screen_meeting_cc_advice' => 'Normally leave this field alone (see documentation).', // TODO: translate - 'meeting_editor_screen_meeting_contact_label' => 'E-mail kontaktowy mityngu:', - 'meeting_editor_screen_meeting_contact_prompt' => 'Podaj e-mail kontaktowy dla tego konkretnego mityngu', - 'meeting_editor_screen_meeting_sb_label' => 'Organ służb:', - 'meeting_editor_screen_meeting_sb_default_value' => 'Nie wybrano organu służb', - 'meeting_editor_screen_meeting_longitude_label' => 'Długość geograficzna:', - 'meeting_editor_screen_meeting_longitude_prompt' => 'Podaj długość geograficzną', - 'meeting_editor_screen_meeting_latitude_label' => 'Szerokość geograficzna:', - 'meeting_editor_screen_meeting_latitude_prompt' => 'Podaj szerokość geograficzną', - 'meeting_editor_screen_meeting_location_label' => 'Położenie:', - 'meeting_editor_screen_meeting_location_prompt' => 'Podaj nazwę miejsca (np. nazwa budynku)', - 'meeting_editor_screen_meeting_info_label' => 'Dodatkowe informacje:', - 'meeting_editor_screen_meeting_info_prompt' => 'Podaj jakiekolwiek dodatkowe informacje odnośnie lokalizacji', - 'meeting_editor_screen_meeting_street_label' => 'Ulica:', - 'meeting_editor_screen_meeting_street_prompt' => 'Podaj adres ulicy', - 'meeting_editor_screen_meeting_neighborhood_label' => 'Okolica:', - 'meeting_editor_screen_meeting_neighborhood_prompt' => 'Podaj okolicę (nie dzielnicę)', - 'meeting_editor_screen_meeting_borough_label' => 'Dzielnica:', - 'meeting_editor_screen_meeting_borough_prompt' => 'Podaj dzielnicę (nie okolicę)', - 'meeting_editor_screen_meeting_city_label' => 'Miasto/miejscowość:', - 'meeting_editor_screen_meeting_city_prompt' => 'Podaj miasto lub miejscowość', - 'meeting_editor_screen_meeting_county_label' => 'Powiat:', - 'meeting_editor_screen_meeting_county_prompt' => 'Podaj powiat', - 'meeting_editor_screen_meeting_state_label' => 'Województwo:', - 'meeting_editor_screen_meeting_state_prompt' => 'Podaj województwo', - 'meeting_editor_screen_meeting_zip_label' => 'Kod pocztowy:', - 'meeting_editor_screen_meeting_zip_prompt' => 'Podaj kod pocztowy', - 'meeting_editor_screen_meeting_nation_label' => 'Państwo:', - 'meeting_editor_screen_meeting_nation_prompt' => 'Podaj państwo', - 'meeting_editor_screen_meeting_comments_label' => 'Komentarze:', - 'meeting_editor_screen_meeting_train_lines_label' => 'Linie pociągowe:', - 'meeting_editor_screen_meeting_bus_lines_label' => 'Linie autobusowe:', - 'meeting_editor_screen_meeting_phone_meeting_number_label' => 'Phone Meeting Dial-in Number:', - 'meeting_editor_screen_meeting_phone_meeting_number_prompt' => 'Enter the dial-in number for a phone or virtual meeting', - 'meeting_editor_screen_meeting_virtual_meeting_link_label' => 'Virtual Meeting Link:', - 'meeting_editor_screen_meeting_virtual_meeting_link_prompt' => 'Enter the link for a virtual meeting', - 'meeting_editor_screen_meeting_virtual_meeting_additional_info_label' => 'Virtual Meeting Additional Information:', - 'meeting_editor_screen_meeting_virtual_meeting_additional_info_prompt' => 'Enter any additional information for joining the virtual meeting, including directly from the app. For example, if the meeting uses Zoom, "Zoom ID: 456 033 8613, Passcode: 1953" would be appropriate.', - 'meeting_editor_screen_meeting_venue_type' => 'Venue Type:', - 'meeting_editor_screen_meeting_venue_type_inperson' => 'In-Person', - 'meeting_editor_screen_meeting_venue_type_virtual' => 'Virtual', - 'meeting_editor_screen_meeting_venue_type_virtualTC' => 'Virtual (temporarily replacing an in-person)', - 'meeting_editor_screen_meeting_venue_type_hybrid' => 'Hybrid (both in-person and virtual)', - 'meeting_editor_screen_meeting_venue_type_validation' => 'You must select a venue type.', - 'meeting_editor_screen_meeting_virtual_info_missing' => 'Virtual or hybrid meetings must have a Virtual Meeting Link, a Phone Meeting Dial-in Number, or Virtual Meeting Additional Information', - 'meeting_editor_screen_meeting_location_warning' => 'Meeting should have a location (at least a city/town and state/province, or a zip/postal code).', - 'meeting_editor_screen_meeting_address_warning' => 'In-person or hybrid meetings should have a street address.', - 'meeting_editor_screen_meeting_url_validation' => 'Virtual Meeting Link is not a valid URL.', - 'meeting_editor_screen_meeting_url_or_phone_warning' => 'Virtual or hybrid meetings should have either a Virtual Meeting Link or a Phone Meeting Dial-in Number', - 'meeting_editor_screen_meeting_additional_warning' => 'Please also fill in Virtual Meeting Additional Information if there is a Virtual Meeting Link.', - 'meeting_editor_screen_in_person_virtual_info_warning' => 'In-person meetings shouldn\'t have any virtual meeting information.', - 'meeting_editor_screen_meeting_virtual_location_info_warning' => 'Virtual meetings shouldn\'t have a location name or address.', - 'meeting_editor_screen_meeting_validation_warning' => 'There are warnings. Are you sure you want to save anyway? If not, press \'cancel\' and go to the Location tab to see the warnings in place and address them.', - 'meeting_editor_screen_meeting_validation_failed' => 'Unable to save due to input errors. Please go to the Location tab to address them, and then retry saving. Errors: ', - 'meeting_editor_screen_meeting_validation_warnings' => 'Input warnings shown on the Location tab: ', - 'meeting_editor_screen_meeting_contact_name_1_label' => 'Imię osoby kontaktowej:', - 'meeting_editor_screen_meeting_contact_email_1_label' => 'Email kontaktowy:', - 'meeting_editor_screen_meeting_contact_phone_1_label' => 'Telefon kontaktowy:', - 'meeting_editor_screen_meeting_contact_name_2_label' => 'Imię drugiej osoby kontaktowej:', - 'meeting_editor_screen_meeting_contact_email_2_label' => 'Drugi email kontaktowy:', - 'meeting_editor_screen_meeting_contact_phone_2_label' => 'Drugi telefon kontaktowy:', - 'meeting_editor_screen_meeting_publish_search_prompt' => 'Szukam:', - 'meeting_editor_screen_meeting_publish_search_pub' => 'Tylko opublikowane mityngi', - 'meeting_editor_screen_meeting_publish_search_unpub' => 'Tylko nieopublikowane mityngi', - 'meeting_editor_screen_meeting_visibility_advice' => 'To nie powinno się wyświetlić przy normalnym wyszukiwaniu mityngów.', - 'meeting_editor_screen_meeting_publish_search_all' => 'Wszystkie mityngi', - 'meeting_editor_screen_meeting_create_button' => 'Dodaj nowy mityng', - 'meeting_editor_screen_delete_button' => 'Usuń ten mityng', - 'meeting_editor_screen_delete_button_confirm' => 'Jesteś pewien, że chcesz usunąć ten mityng?', - 'meeting_editor_screen_cancel_button' => 'Anuluj', - 'logout' => 'Wyloguj', - 'meeting_editor_screen_cancel_confirm' => 'Jesteś pewien, że chcesz przestać edytować ten mityng i utracić wszystkie zmiany?', - 'meeting_lookup_failed' => 'Wyszukiwanie adresu nie powiodło się.', - 'meeting_lookup_failed_not_enough_address_info' => 'Nie ma wystarczającej ilości informacji adresowych by wyszukać.', - 'meeting_create_button_name' => 'Zapisz jako nowy mityng', - 'meeting_saved_as_a_copy' => 'Zapisz ten mityng jako kopię (tworzy nowy mityng)', - 'meeting_save_buttonName' => 'Zapisz zmiany w tym mityngu', - 'meeting_editor_tab_bar_basic_tab_text' => 'Podstawy', - 'meeting_editor_tab_bar_location_tab_text' => 'Położenie', - 'meeting_editor_tab_bar_format_tab_text' => 'Format', - 'meeting_editor_tab_bar_other_tab_text' => 'Inne', - 'meeting_editor_tab_bar_history_tab_text' => 'Historia', - 'meeting_editor_result_count_format' => '%d mityngów znaleziono', - 'meeting_id_label' => 'ID: mityngu', - 'meeting_editor_default_zoom' => '13', - 'meeting_editor_default_weekday' => '2', - 'meeting_editor_default_start_time' => '20:30:00', - 'login_banner' => 'Basic Meeting List Toolbox', - 'login_underbanner' => 'Root Server Administration Console', - 'login' => 'Login ID', - 'password' => 'Hasło', - 'button' => 'Zaloguj się', - 'cookie' => 'Musisz włączyć obsługę cookies by zarządzać tym serwerem.', - 'noscript' => 'Nie możesz zarządzać tą stroną bez JavaScriptu.', - 'title' => 'Zaloguj się, by zarządzać serwerem.', - 'edit_Meeting_object_not_found' => 'BŁĄD: Mityng nie został znaleziony.', - 'edit_Meeting_object_not_changed' => 'BŁAD: Mityng nie został zmieniony.', - 'edit_Meeting_auth_failure' => 'Nie masz uprawnień do edytowania tego mityngu.', - 'not_auth_1' => 'NIEAUTORYZOWANY', - 'not_auth_2' => 'Nie masz uprawnień do zarządzania tym serwerem.', - 'not_auth_3' => 'Wystąpił problem z podaną nazwą użytkownika lub hasłem.', - 'email_format_bad' => 'Podany adres e-mail ma błędny format.', - 'history_header_format' => '
%sby %s
', - 'history_no_history_available_text' => '

Brak historii dostępnej dla tego mityngu

', - 'service_body_editor_disclosure' => 'Zarządzanie organem służb', - 'service_body_change_fader_success_text' => 'Organ służb został pomyślnie zmieniony', - 'service_body_change_fader_fail_text' => 'Nieudana próba zmiany organu służb', - 'service_body_editor_screen_sb_id_label' => 'ID:', - 'service_body_editor_screen_sb_name_label' => 'Nazwa:', - 'service_body_name_default_prompt_text' => 'Podaj nazwę tego organu służb', - 'service_body_parent_popup_label' => 'Organ nadrzędny organu służb:', - 'service_body_parent_popup_no_parent_option' => 'Brak organu nadrzędnego (najwyższy poziom)', - 'service_body_editor_screen_sb_admin_user_label' => 'Główny administrator:', - 'service_body_editor_screen_sb_admin_description_label' => 'Opis:', - 'service_body_description_default_prompt_text' => 'Podaj opis tego organu służb', - 'service_body_editor_screen_sb_admin_email_label' => 'E-mail kontaktowy:', - 'service_body_email_default_prompt_text' => 'Podaj e-mail kontaktowy tego organu służb', - 'service_body_editor_screen_sb_admin_uri_label' => 'URL strony internetowej:', - 'service_body_uri_default_prompt_text' => 'Podaj URL strony internetowej tego organu służb', - 'service_body_editor_screen_sb_admin_full_editor_label' => 'Pełni edytorzy listy mityngów:', - 'service_body_editor_screen_sb_admin_full_editor_desc' => 'Użytkownicy mogący edytować dowolny mityng w tym organie służb', - 'service_body_editor_screen_sb_admin_editor_label' => 'Podstawowi edytorzy listy mityngów:', - 'service_body_editor_screen_sb_admin_editor_desc' => 'Użytkownicy mogący edytować jedynie nieopublikowane mityngi w tym organie służb.', - 'service_body_editor_screen_sb_admin_observer_label' => 'Obserwatorzy:', - 'service_body_editor_screen_sb_admin_observer_desc' => 'Użytkownicy mogący zobaczyć ukryte informacje (np. adres e-mail), ale bez możliwości edycji.', - 'service_body_dirty_confirm_text' => 'Wprowadziłeś zmiany dla tego organu służb. Chcesz utracić wprowadzone zmiany?', - 'service_body_save_button' => 'Zapisz zmiany tego organu służb', - 'service_body_create_button' => 'Stwórz organ służb', - 'service_body_delete_button' => 'Usuń ten organ służb', - 'service_body_delete_perm_checkbox' => 'Usuń trwale ten organ służb', - 'service_body_delete_button_confirm' => 'Jesteś pewien, że chcesz usunąć ten organ służb? Upewnij się, że wszystkie mityngi są usunięte lub przeniesione do innego organu służb przed wykonaniem tej akcji.', - 'service_body_delete_button_confirm_perm' => 'Ten organ służb zostanie usunięty trwale!', - 'service_body_change_fader_create_success_text' => 'Organ służb został pomyślnie utworzony', - 'service_body_change_fader_create_fail_text' => 'Tworzenie organu służb nie powiodło się', - 'service_body_change_fader_delete_success_text' => 'Organ służb został pomyślnie usunięty', - 'service_body_change_fader_delete_fail_text' => 'Usuwanie organu służb nie powiodło się', - 'service_body_change_fader_fail_no_data_text' => 'Zmiana organu służb nie powiodła się, ponieważ nie dostarczono żadnych danych', - 'service_body_change_fader_fail_cant_find_sb_text' => 'Zmiana organu służb nie powiodła się, ponieważ nie odnaleziono tego organu służb', - 'service_body_change_fader_fail_cant_update_text' => 'Zmiana organu służb nie powiodła się, ponieważ organ służb nie był zaktualizowany', - 'service_body_change_fader_fail_bad_hierarchy' => 'Zmiana organu służb nie powiodła się, ponieważ wybrany właściciel organu służb jest poniżej tego organu i nie może być użyty', - 'service_body_cancel_button' => 'Przywróć do oryginału', - 'service_body_editor_type_label' => 'Rodzaj organu służb:', - 'service_body_editor_type_c_comdef_service_body__GRP__' => 'Grupa', - 'service_body_editor_type_c_comdef_service_body__COP__' => 'Współpraca', - 'service_body_editor_type_c_comdef_service_body__ASC__' => 'Okręgowy Komitet Służebnych', - 'service_body_editor_type_c_comdef_service_body__RSC__' => 'Konferencja Służb Regionalnych', - 'service_body_editor_type_c_comdef_service_body__WSC__' => 'Konferencja Służb Światowych', - 'service_body_editor_type_c_comdef_service_body__MAS__' => 'Metro Area', - 'service_body_editor_type_c_comdef_service_body__ZFM__' => 'Zonal Forum', - 'service_body_editor_type_c_comdef_service_body__GSU__' => 'Grupowa jednostka służby', - 'service_body_editor_type_c_comdef_service_body__LSU__' => 'Lokalna jednostka służby', - 'service_body_editor_screen_helpline_label' => 'Linia pomocy:', - 'service_body_editor_screen_helpline_prompt' => 'Podaj numer telefonu dla linii pomocy', - 'service_body_editor_uri_naws_format_text' => 'Zbierz mityngi z tego organu służb jako plik zgodny z NAWS', - 'edit_Meeting_meeting_id' => 'ID mityngu:', - 'service_body_editor_create_new_sb_option' => 'Stwórz nowy organ służb', - 'service_body_editor_screen_world_cc_label' => 'Kod Komitetu Światowego:', - 'service_body_editor_screen_world_cc_prompt' => 'Podaj kod Komitetu Światowego', - 'user_editor_disclosure' => 'Zarządzanie użytkownika', - 'user_editor_create_new_user_option' => 'Utwórz nowego użytkownika', - 'user_editor_screen_sb_id_label' => 'ID:', - 'user_editor_account_login_label' => 'Login:', - 'user_editor_login_default_text' => 'Wpisz Login', - 'user_editor_account_type_label' => 'Użytkownik:', - 'user_editor_user_owner_label' => 'Właściciel: ', - 'user_editor_account_type_1' => 'Administrator serwera', - 'user_editor_account_type_2' => 'Służebny administrator', - 'user_editor_account_type_3' => 'Służebny edytor', - 'user_editor_account_type_5' => 'Służebny obserwator', - 'user_editor_account_type_4' => 'Dezaktywowany użytkownik', - 'user_editor_account_name_label' => 'Nazwa użytkownika:', - 'user_editor_name_default_text' => 'Wpisz nazwę użytkownika', - 'user_editor_account_description_label' => 'Opis:', - 'user_editor_description_default_text' => 'Wprowadź opis użytkownika', - 'user_editor_account_email_label' => 'Email:', - 'user_editor_email_default_text' => 'Wprowadź adres e-mail', - 'user_change_fader_success_text' => 'Użytkownik zmieniony pomyślnie', - 'user_change_fader_fail_text' => 'Nie udało się zmienić użytkwonika', - 'user_change_fader_create_success_text' => 'Użytkownik utworzony pomyślnie', - 'user_change_fader_create_fail_text' => 'Nie udało się utworzyć użytkownika', - 'user_change_fader_create_fail_already_exists' => 'Nazwa użytkownika istnieje już w bazie.', - 'user_change_fader_delete_success_text' => 'Użytkownik usunięty pomyślnie', - 'user_change_fader_delete_fail_text' => 'Nie udało się usunąć użytkownika', - 'user_save_button' => 'Zapisz zmiany dla tego użytkownika', - 'user_create_button' => 'Utwórz tego nowego użytkownika', - 'user_cancel_button' => 'Przywróć domyślne', - 'user_delete_button' => 'Usuń tego użytkownika', - 'user_delete_perm_checkbox' => 'Usuń tego użytkownika nieodwracalnie', - 'user_password_label' => 'Zmień hasło dla:', - 'user_new_password_label' => 'Ustaw hasło:', - 'user_password_default_text' => 'Nie zmieniaj tego pola, chyba, że chcesz zmienić hasło', - 'user_new_password_default_text' => 'Musisz wpisać hasło dla nowego użytkownika', - 'user_dirty_confirm_text' => 'Wprowadzono zmiany dla użytkownika. Czy chcesz utracić te zmiany?', - 'user_delete_button_confirm' => 'Czy na pewno chcesz usunąć tego użytkownika?', - 'user_delete_button_confirm_perm' => 'Użytkownik zostanie nieodwracalnie usunięty!', - 'user_create_password_alert_text' => 'Nowy użytkownik musi posiadać hasło. Nie wprowadzono hasła dla użytkownika.', - 'user_change_fader_fail_no_data_text' => 'Nie udało się wprowadzić zmian dla użytkownika. Nie wprowadzono wszystkich danych', - 'user_change_fader_fail_cant_find_sb_text' => 'Nie udało się wprowadzić zmian dla użytkownika.Nie znaleziono użytkownika', - 'user_change_fader_fail_cant_update_text' => 'Nie udało się wprowadzić zmian dla użytkownika', - 'format_editor_disclosure' => 'Administracja formatu', - 'format_change_fader_change_success_text' => 'Format zmieniony pomyślnie', - 'format_change_fader_change_fail_text' => 'Nie udało się zmienić formatu', - 'format_change_fader_create_success_text' => 'Format utworzony pomyślnie', - 'format_change_fader_create_fail_text' => 'Nie udało się utworzyć formatu', - 'format_change_fader_delete_success_text' => 'Format usunięty pomyślnie', - 'format_change_fader_delete_fail_text' => 'Nie udało się usunąć formatu', - 'format_change_fader_fail_no_data_text' => 'Nie udało się usunąć formatu z powodu brakujących danych', - 'format_change_fader_fail_cant_find_sb_text' => 'Nie udało się usunąć formatu, nie znaleziono formatu', - 'format_change_fader_fail_cant_update_text' => 'Nie udało się usunąć formatu, nie zaktualizowano formatu', - 'format_editor_name_default_text' => 'Podaj krótką nazwę', - 'format_editor_description_default_text' => 'Podaj bardziej szczegółowy opis', - 'format_editor_create_format_button_text' => 'Utwórz format', - 'format_editor_cancel_create_format_button_text' => 'Anuluj', - 'format_editor_create_this_format_button_text' => 'Utwórz ten format', - 'format_editor_change_format_button_text' => 'Zmień ten format', - 'format_editor_delete_format_button_text' => 'Usuń ten format', - 'format_editor_reset_format_button_text' => 'Przywróć do oryginału', - 'need_refresh_message_fader_text' => 'Odśwież stronę przed użyciem tej sekcji', - 'need_refresh_message_alert_text' => 'Ponieważ wprowadziłeś zmiany w Administracji Serwera, Administracji Organów Służb, Administracji Użytkowników lub Administracji Formatów, informacje zawarte w tej sekcji mogą już nie być aktualne. Proszę odświeżyć stronę poprzez wylogowanie się i zalogowanie się ponownie.', - 'format_editor_delete_button_confirm' => 'Czy na pewno chcesz usunąć ten format?', - 'format_editor_delete_button_confirm_perm' => 'Ten format zostanie usunięty nieodwracalnie!', - 'format_editor_missing_key' => 'This format should have an entry for every language (at least a key).', // TODO: translate - 'format_editor_reserved_key' => 'This key is reserved for a venue type format - please use something different.', // TODO: translate - 'min_password_length_string' => 'Hasło jest za krótkie! Hasło powinno posiadać minimum %d znaków!', - 'AJAX_Auth_Failure' => 'Nie udało się autoryzować operacji. Możliwe, że istnieje problem z konfiguracją serwera.', - 'Maps_API_Key_Warning' => 'Wystąpił problem z kluczem Google Maps API.', - 'Maps_API_Key_Not_Set' => 'Nie ustalono klucza Google Maps API.', - 'Observer_Link_Text' => 'Meeting Browser', - 'Data_Transfer_Link_Text' => 'Importuj dane mityngu (UWAGA: istniejące dane zostaną nadpisane!)', - 'MapsURL' => 'https://maps.google.com/maps?q=##LAT##,##LONG##+(##NAME##)&ll=##LAT##,##LONG##', - 'hidden_value' => 'Nie można wyświetlić danych - brak autoryzacji', - 'Value_Prompts' => array( - 'id_bigint' => 'ID Mityngu', - 'worldid_mixed' => 'ID Służb Światowych', - 'service_body' => 'Organ służb', - 'service_bodies' => 'Organy służb', - 'weekdays' => 'Dni powszednie', - 'weekday' => 'Mityng spotyka się w każdy', - 'start_time' => 'Mityng rozpoczyna się o', - 'duration_time' => 'Mityng trwa', - 'location' => 'Lokalizacja', - 'duration_time_hour' => 'Godzina', - 'duration_time_hours' => 'Godziny', - 'duration_time_minute' => 'Minuta', - 'duration_time_minutes' => 'Minuty', - 'lang_enum' => 'Język', - 'formats' => 'Formaty', - 'distance' => 'Odległość od centrum miasta', - 'generic' => 'Mityng NA', - 'close_title' => 'Zamknij okno ze szczegółami mityngu', - 'close_text' => 'Zamknij okno', - 'map_alt' => 'Mapa dojazdu do mityngu', - 'map' => 'Podążaj za linkiem by wyświetlić mapę', - 'title_checkbox_unpub_meeting' => 'Ten mityng nie został opublikowany. Nie będzie dostępny w wynikach wyszukiwania.', - 'title_checkbox_copy_meeting' => 'Ten mityng jest duplikatem istniejącego mityngu. Nie został opublikowany. Nie będzie widoczny w wynikach wyszukiwania' - ), - 'world_format_codes_prompt' => 'Format NAWS:', - 'world_format_codes' => array( - '' => 'Brak', - 'OPEN' => 'Otwarty', - 'CLOSED' => 'Zamknięty', - 'WCHR' => 'Wózki inwalidzkie', - 'BEG' => 'Nowoprzybili', - 'BT' => 'Tekst podstawowe', - 'CAN' => 'Świeczka', - 'CPT' => '12 Tradycji', - 'CW' => 'Dzieci mile widziane', - 'DISC' => 'Dyskusja', - 'GL' => 'LGBTQ', - 'IP' => 'Broszura Informacyjna', - 'IW' => 'To Działa - Jak i Dlaczego', - 'JFT' => 'Właśnie Dzisiaj', - 'LC' => 'Życie w czystości', - 'LIT' => 'Analiza książek', - 'M' => 'Mężczyźni', - 'MED' => 'Medytacja', - 'NS' => 'Zakaz palenia', - 'QA' => 'Pytania i ODpowiedzi', - 'RA' => 'Ograniczone uczestnicwo', - 'S-D' => 'Speaker/Discussion', // TODO translate - 'SMOK' => 'Palenie', - 'SPK' => 'Spiker', - 'STEP' => 'Krok', - 'SWG' => 'Przewodnik pracy nad Krokami', - 'TOP' => 'Temat', - 'TRAD' => 'Tradycja', - 'VAR' => 'Zmienny format', - 'W' => 'Kobiety', - 'Y' => 'Młodzi ludzie', - 'LANG' => 'Alternatywny język', - 'GP' => 'Guiding Principles', - 'NC' => 'Bez dzieci', - 'CH' => 'Zamknięty w święta', - 'VM' => 'Virtual', // TODO translate - 'HYBR' => 'Virtual and In-Person', // TODO translate - 'TC' => 'Temporarily Closed Facility', // TODO translate - 'SPAD' => 'Spiritual Principle a Day', // TODO translate - ), - 'format_type_prompt' => 'Typ formatu:', - 'format_type_codes' => array( - '' => 'Brak', - 'FC1' => 'Format mityngu (spiker, analiza literatury etc.)', - 'FC2' => 'Kod lokalizacji (dostęp dla wózków inwalidzkich, ograniczony parking, etc.)', - 'FC3' => 'Potrzeby i ograniczenia (mityng mężczyzn, LGBTQ, zakaz dzieci etc.)', - 'O' => 'Dostępność dla nieuzależnionych (Otwarty, Zamknięty)', - 'LANG' => 'Język', - 'ALERT' => 'Format powinien być łatwo widoczny (Wymagania dot. czasu czystości, etc.)', - ), - - 'cookie_monster' => 'Ta strona używa ciasteczek do przechowywania Twoich preferencji językowych.', - 'main_prompts' => array( - 'id_bigint' => 'ID', - 'worldid_mixed' => 'Światowe ID', - 'shared_group_id_bigint' => 'Nieużywane', - 'service_body_bigint' => 'ID komitetu', - 'weekday_tinyint' => 'Dzień powszedni', - 'venue_type' => 'Venue Type', - 'start_time' => 'Czas rozpoczęcia', - 'duration_time' => 'Czas trwania', - 'time_zone' => 'Time Zone', - 'formats' => 'Formaty', - 'lang_enum' => 'Język', - 'longitude' => 'Długość geograficzna', - 'latitude' => 'Szerokość geograficzna', - 'published' => 'Opublikowany', - 'email_contact' => 'Kontakt e-mail', - ), - 'check_all' => 'Check All', - 'uncheck_all' => 'Uncheck All', - 'automatically_calculated_on_save' => 'Automatically calculated on save.' -); -$email_contact_strings = array( - 'meeting_contact_form_subject_format' => "[MEETING LIST CONTACT] %s", - 'meeting_contact_message_format' => "%s\n--\nTa wiadomość dotyczy mityngu o nazwie \"%s\", który odbywa się %s, %s.\nBrowser Link: %s\nLink do edycji: %s\nZostał wysłany z serwera z listą mityngów, a nadawca nie zna Twojego adresu e-mail.\nPamiętaj, że, odpowiadając na tę wiadomość, ujawnisz swój adres e-mail.\nJeśli użyjesz \"Odpowiedz wszystkim\", a jest więcej niż jeden odbiorca, możesz ujawnić adresy e-mail innych użytkowników.\nUszanuj, proszę, anonimowość użytkowników; włączając w to oryginalnego nadawcę tego e-maila." -); - -$change_type_strings = array( - '__THE_MEETING_WAS_CHANGED__' => 'Mityng został zmieniony.', - '__THE_MEETING_WAS_CREATED__' => 'Mityng został utworzony.', - '__THE_MEETING_WAS_DELETED__' => 'Mityng został usunięty.', - '__THE_MEETING_WAS_ROLLED_BACK__' => 'Mityng został przywrócony do poprzedniej wersji', - - '__THE_FORMAT_WAS_CHANGED__' => 'Format został zmieniony.', - '__THE_FORMAT_WAS_CREATED__' => 'Format został utworzonty.', - '__THE_FORMAT_WAS_DELETED__' => 'Format został usunięty.', - '__THE_FORMAT_WAS_ROLLED_BACK__' => 'Format został przywrócony do poprzedniej wersji.', - - '__THE_SERVICE_BODY_WAS_CHANGED__' => 'Organ służb został zmieniony.', - '__THE_SERVICE_BODY_WAS_CREATED__' => 'Organ służb został utworzony.', - '__THE_SERVICE_BODY_WAS_DELETED__' => 'Organ służb został usunięty.', - '__THE_SERVICE_BODY_WAS_ROLLED_BACK__' => 'Organ służb został przywrócony do poprzedniej wersji.', - - '__THE_USER_WAS_CHANGED__' => 'Użytkownik został zmieniony.', - '__THE_USER_WAS_CREATED__' => 'Użytkownik został utworzony.', - '__THE_USER_WAS_DELETED__' => 'Użytkownik został usunięty.', - '__THE_USER_WAS_ROLLED_BACK__' => 'Użytkownik został przywrócony do poprzedniej wersji.', - - '__BY__' => 'przez', - '__FOR__' => 'dla' -); - -$detailed_change_strings = array( - 'was_changed_from' => 'został zmieniony z', - 'to' => 'na', - 'was_changed' => 'został zmieniony', - 'was_added_as' => 'został dodany jako', - 'was_deleted' => 'został usunięty', - 'was_published' => 'Mityng został opublikowany', - 'was_unpublished' => 'Mityng był nieopublikowany', - 'formats_prompt' => 'Format mityngu', - 'duration_time' => 'Czas trwania mityngu', - 'start_time' => 'Czas rozpoczęcia mityngu', - 'longitude' => 'Długość geograficzna mityngu', - 'latitude' => 'Szerokość geograficzna mityngu', - 'sb_prompt' => 'Mityng zmienił swój organ służb z', - 'id_bigint' => 'ID mityngu', - 'lang_enum' => 'Język mityngu', - 'worldid_mixed' => 'Udostępnione ID grupy', // TODO: translate The World Committee Code - 'weekday_tinyint' => 'Dzień tygodnia, w którym odbywa się mityng', - 'non_existent_service_body' => 'Organ służb już nie istnieje', -); - -defined('_END_CHANGE_REPORT') or define('_END_CHANGE_REPORT', '.'); diff --git a/src/legacy/local_server/server_admin/lang/pt/data_transfer_strings.php b/src/legacy/local_server/server_admin/lang/pt/data_transfer_strings.php deleted file mode 100755 index 624c60e08..000000000 --- a/src/legacy/local_server/server_admin/lang/pt/data_transfer_strings.php +++ /dev/null @@ -1,45 +0,0 @@ -.*/ - defined('BMLT_EXEC') or die('Cannot Execute Directly'); // Makes sure that this file is in the correct context. - - $comdef_data_transfer_strings = array ( 'key_strings' => array ( 'id_bigint' => 1, - 'worldid_mixed' => 1, - 'shared_group_id_bigint' => 1, - 'service_body_bigint' => 1, - 'weekday_tinyint' => 1, - 'start_time' => 1, - 'duration_time' => 1, - 'formats' => 1, - 'lang_enum' => 1, - 'longitude' => 1, - 'latitude' => 1, - 'published' => 1, - 'email_contact' => 1 - ), - - 'days' => array ( 'Sunday', - 'Monday', - 'Tuesday', - 'Wednesday', - 'Thursday', - 'Friday', - 'Saturday' - ), - ); diff --git a/src/legacy/local_server/server_admin/lang/pt/install_wizard_strings.php b/src/legacy/local_server/server_admin/lang/pt/install_wizard_strings.php deleted file mode 100755 index 8ca9805bd..000000000 --- a/src/legacy/local_server/server_admin/lang/pt/install_wizard_strings.php +++ /dev/null @@ -1,165 +0,0 @@ -.*/ - defined('BMLT_EXEC') or die('Cannot Execute Directly'); // Makes sure that this file is in the correct context. - - global $comdef_install_wizard_strings; - - $comdef_install_wizard_strings = array ( - 'Database_Version_Error' => 'ERROR: You must have PHP Version 5.6 or greater installed on this server!', - 'Database_PDO_Error' => 'ERROR: You do not have PHP PDO installed!', - 'Database_Type_Error' => 'ERROR: Even though you have PDO, you have no database drivers installed!', - 'Database_Type_MySQL_Error' => 'ERROR: Even though you have PDO and you have database drivers installed, none of the are MySQL (the only supported driver)!', - 'Database_TestButton_Text' => 'TEST', - 'Database_TestButton_Success' => 'The database connection was successful.', - 'Database_TestButton_Fail' => 'The database connection failed: ', - 'Database_TestButton_Fail2' => 'The database connection failed because there is already an initialized database.', - 'Database_Whitespace_Note' => 'Warning: %s has whitespace at the beginning or end.', - - 'AJAX_Handler_DB_Connect_Error' => 'The database connection failed! Please make sure that the database exists, IS COMPLETELY EMPTY, the user is created, and that user has full permissions on the empty database.', - 'AJAX_Handler_DB_Established_Error' => 'The database already exists, and has been set up! You cannot use this setup to overwrite an existing database!', - 'AJAX_Handler_DB_Incomplete_Error' => 'There is not enough information to initialize the database!', - - 'NoDatabase_Note_AlreadySet' => 'The database has already been initialized with the provided table prefix. Please choose a new one.', - 'NoDatabase_Note_GenericError' => 'There is an error connecting to the database. Please check your database settings.', - 'NoDatabase_Note_ClickHere' => 'Click here to go back to the database set up page.', - 'NoDatabase_Note_PasswordIssue' => 'You must choose a username and password for the Server Administrator user.', - 'NoDatabase_Note_ServerSettings_ClickHere' => 'Click here to go back to the server settings page.', - 'NoServerAdmin_Note_AlreadySet' => 'There is already an existing database, so you cannot set up a Server Administrator account (One already exists).', - 'NeedLongerPasswordNote' => 'This password is too short. It must be at least %d characters long.', - - 'Prev_Button' => 'PREVIOUS', - 'Next_Button' => 'NEXT', - - 'Page_1_Tab' => 'STEP 1: Database', - 'Page_1_Heading' => 'Database Connection Settings', - 'Page_1_Text' => 'Before you can apply the settings on this page, you must set up a new COMPLETELY EMPTY database, and create a database user that has full user rights on that database.', - - 'Database_Name' => 'Database Name:', - 'Database_Name_Default_Text' => 'Enter A Database Name', - 'Database_Type' => 'Database Type:', - 'Database_Host' => 'Database Host:', - 'Database_Host_Default_Text' => 'Enter A Database Host', - 'Database_Host_Additional_Text' => 'This is usually "localhost."', - 'Table_Prefix' => 'Table Prefix:', - 'Table_Prefix_Default_Text' => 'Enter A Table Prefix', - 'Table_Prefix_Additional_Text' => 'Only for multiple root servers sharing a database.', - 'Database_User' => 'Database User:', - 'Database_User_Default_Text' => 'Enter A Database User Name', - 'Database_PW' => 'Database Password:', - 'Database_PW_Default_Text' => 'Enter A Database Password', - 'Database_PW_Additional_Text' => 'Make this an ugly, difficult password. It has a great deal of power, and you will never need to remember it.', - - 'Maps_API_Key_Warning' => 'There is a problem with the Google Maps API Key.', - 'Maps_API_Key_Not_Set' => 'The Google Maps API key is not set.', - 'Maps_API_Key_Valid' => 'Google Maps API Key is valid.', - 'Maps_API_Key_ClickHere' => 'Click here to go back to the Google Maps API Key set up page.', - - 'Page_2_Tab' => 'STEP 2: Google Maps API Settings', - 'Page_2_Heading' => 'Google Maps API Settings', - 'Page_2_API_Key_Prompt' => 'Enter the Google API Key for Geocoding:', - 'Page_2_API_Key_Set_Button' => 'TEST KEY', - 'Page_2_API_Key_Not_Set_Prompt' => 'SET API KEY FIRST', - 'Page_2_Text' => 'When saving a meeting, the BMLT Root Server uses the Google Maps API to determine the latitude and longitude for the meeting address. These settings are required to allow the BMLT Root Server to communicate with the Google Maps API.', - - 'Page_3_Tab' => 'STEP 3: Server Settings', - 'Page_3_Heading' => 'Set Various Global Server Settings', - 'Page_3_Text' => 'These are a few settings that affect the administration and general configuration of this server. Most server settings are done in the server itself.', - 'Admin_Login' => 'Server Administrator Login:', - 'Admin_Login_Default_Text' => 'Enter A Server Administrator Login', - 'Admin_Login_Additional_Text' => 'This is the login string for the Server Administrator.', - 'Admin_Password' => 'Server Administrator Password:', - 'Admin_Password_Default_Text' => 'Enter A Server Administrator Password', - 'Admin_Password_Additional_Text' => 'Make sure that this is a non-trivial password! It has a great deal of power! (Also, don\'t forget it).', - 'ServerAdminName' => 'Server Administrator', - 'ServerAdminDesc' => 'Main Server Administrator', - 'ServerLangLabel' => 'Default Server Language:', - 'DistanceUnitsLabel' => 'Distance Units:', - 'DistanceUnitsMiles' => 'Miles', - 'DistanceUnitsKM' => 'Kilometres', - 'SearchDepthLabel' => 'Density of Meetings For Automatic Search:', - 'SearchDepthText' => 'This is an approximation of how many meetings need to be found in the automatic radius selection. More meetings means a bigger radius.', - 'HistoryDepthLabel' => 'How Many Meeting Changes To Save:', - 'HistoryDepthText' => ' The longer the history, the larger the database will become.', - 'TitleTextLabel' => 'The Title Of The Administration Screen:', - 'TitleTextDefaultText' => 'Enter A Short Title For the Editing Login Page', - 'BannerTextLabel' => 'Prompt For Administration Login:', - 'BannerTextDefaultText' => 'Enter A Short Prompt For The Login Page', - 'RegionBiasLabel' => 'Region Bias:', - 'PasswordLengthLabel' => 'Minimum Password Length:', - 'PasswordLengthExtraText' => 'This will also affect the Server Administrator password, above.', - 'DefaultClosedStatus' => 'Meetings Are Considerd "CLOSED" by Default:', - 'DefaultClosedStatusExtraText' => 'This primarily affects the export to NAWS.', - 'DurationLabel' => 'Default Meeting Duration:', - 'DurationHourLabel' => 'Hours', - 'DurationMinutesLabel' => 'Minutes', - 'LanguageSelectorEnableLabel' => 'Display Language Selector On Login:', - 'LanguageSelectorEnableExtraText' => 'If you select this, a popup menu will appear in the login screen, so administrators can select their language.', - 'SemanticAdminLabel' => 'Enable Semantic Administration:', - 'SemanticAdminExtraText' => 'If not checked, then all administration must be done via the Root Server login (No apps).', - 'EmailContactEnableLabel' => 'Allow Email Contacts From Meetings:', - 'EmailContactEnableExtraText' => 'If you select this, site visitors will be able to send emails from meeting records.', - 'EmailContactAdminEnableLabel' => 'Include Service Body Administrator On These Emails:', - 'EmailContactAdminEnableExtraText' => 'Sends copies of these emails to the Service Body Administrator (if they are not the primary recipient).', - 'EmailContactAllAdminEnableLabel' => 'Include All Service Body Administrators On These Emails:', - 'EmailContactAllAdminEnableExtraText' => 'Sends copies of these emails to all of the relevant Service Body Administrators.', - - 'Page_4_Initialize_Root_Server_Heading' => 'Initialize the Root Server', - 'Page_4_Initialize_Root_Server_Text' => 'The button below will initialize the Root Server with an empty database and a Server Administrator user.', - 'Page_4_Initialize_Root_Server_Button' => 'Initialize Root Server', - - 'Page_4_Tab' => 'STEP 4: Save The Settings', - 'Page_4_Heading' => 'Create the Settings File', - 'Page_4_Text' => 'The root server was unable to create the settings file for you. Instead, we ask you to create it yourself, via FTP or a control panel file manager, name it "auto-config.inc.php", and paste the following text into the file:', - - 'NAWS_Export_Spreadsheet_Optional' => 'NAWS Export Spreadsheet (Optional): ', - 'NAWS_Export_Spreadsheet_Initially_Publish' => 'Initialize imported meetings to \'published\': ', - - 'DefaultPasswordLength' => 10, - 'DefaultMeetingCount' => 10, - 'DefaultChangeDepth' => 5, - 'DefaultDistanceUnits' => 'mi', - 'DefaultDurationTime' => '01:30:00', - 'DurationTextInitialText' => 'N.A. Meetings are usually 90 minutes long (an hour and a half), unless otherwise indicated.', - 'time_format' => 'g:i A', - 'change_date_format' => 'g:i A, n/j/Y', - 'BannerTextInitialText' => 'Administration Login', - 'TitleTextInitialText' => 'Basic Meeting List Toolbox Administration', - 'DefaultRegionBias' => 'us', - 'search_spec_map_center' => array ( 'longitude' => -118.563659, 'latitude' => 34.235918, 'zoom' => 6 ), - 'DistanceChoices' => array ( 2, 5, 10, 20, 50 ), - 'HistoryChoices' => array ( 1, 2, 3, 5, 8, 10, 15 ), - 'PW_LengthChices' => array ( 6, 8, 10, 12, 16 ), - 'ServerAdminDefaultLogin' => 'serveradmin', - - 'Explanatory_Text_1_Initial_Intro' => 'This install wizard will guide you through the process of creating an initial database, as well as a configuration file. In the final step, we will create a settings file, and initialize an empty database.', - 'Explanatory_Text_1_DB_Intro' => 'The first thing that you need to do, is create a new, EMPTY database, and a database user that has full access to that database. This is usually done via your Web site Control Panel. Once you have created the database, you need to enter the information about that database into the text items on this page.', - - 'Explanatory_Text_2_Region_Bias_Intro' => 'The "Region Bias" is a code that is sent to Google when a location search is done, and can help Google to make sense of ambiguous search queries.', - 'Explanatory_Text_2_API_key_Intro' => 'The "API Key" is a key that you need to register with Google in order to be able to use their mapping service.', - 'Explanatory_Text_2_API_key_2_Intro' => 'You will need to provide a valid API Key in order to create new meetings in the Root Server.', - - 'Explanatory_Text_3_Server_Admin_Intro' => 'The Server Administrator is the main user for the server. It is the only account that can create new users and Service bodies, and is very powerful. You should create a login ID and a non-trivial password for this account. You\'ll be able to modify the other aspects of the account on the main server, once the database has been set up.', - 'Explanatory_Text_3_Misc_Intro' => 'These are various settings that affect how the root server behaves and appears.', - - 'Explanatory_Text_4_Main_Intro' => 'If you have entered the database information, provided a valid Google Maps API Key, and specified the login information for the Server Administrator, then you can initialize the root server here. Remember that the database must be COMPLETELY EMPTY of BMLT Root Server tables for this server (It can have tables for other servers or services).', - 'Explanatory_Text_4_NAWS_Export' => 'Optionally, you can import the meetings from a NAWS export spreadsheet. Uncheck the box to initialize them to \'unpublished\'. (This is useful if many of the new meetings will need to be edited or deleted, and you don\'t want them showing up in the meantime.)', - 'Explanatory_Text_4_File_Intro' => 'The text in the box below is the PHP source code for the main settings file. You will need to create a file on the server with this text in it. The file is at the same level as the main server directory for the root server.', - 'Explanatory_Text_4_File_Extra' => 'You also need to make sure that the file permissions are restricted (chmod 0644). This prevents the file from being written, and the root server will not run unless the file has the correct permissions.', - 'Page_4_PathInfo' => 'The file needs to be placed as %s/auto-config.inc.php, which is where your %s directory is. After the file has been created and you have put the above text into it, you should execute the following command to make sure that the permissions are correct:', - 'Page_4_Final' => 'Once all this is complete, refresh this page, and you should see the root server login page.', - 'FormatLangNamesLabel' => 'Enter extra languages in format code1:name1 (example "fa:farsi ru:russian"):', - ); diff --git a/src/legacy/local_server/server_admin/lang/pt/name.txt b/src/legacy/local_server/server_admin/lang/pt/name.txt deleted file mode 100755 index 811b10b44..000000000 --- a/src/legacy/local_server/server_admin/lang/pt/name.txt +++ /dev/null @@ -1 +0,0 @@ -Português \ No newline at end of file diff --git a/src/legacy/local_server/server_admin/lang/pt/server_admin_strings.inc.php b/src/legacy/local_server/server_admin/lang/pt/server_admin_strings.inc.php deleted file mode 100644 index a499afa88..000000000 --- a/src/legacy/local_server/server_admin/lang/pt/server_admin_strings.inc.php +++ /dev/null @@ -1,488 +0,0 @@ -. */ - -defined('BMLT_EXEC') or die('Cannot Execute Directly'); // Certifique-se que este arquivo esteja no contexto correto. - -$comdef_server_admin_strings = array('server_admin_disclosure' => 'Administração do Servidor', - 'server_admin_naws_spreadsheet_label' => 'Planilha atualizada de IDs Mundiais:', // TODO: was changed to "Updated World Committee Codes Spreadsheet" - 'update_world_ids_button_text' => 'Atualizar IDs Mundiais de reunião', // TODO: was changed to "Update World Committee Codes" - 'update_world_ids_from_spreadsheet_dropdown_text' => 'Atualizar IDs Mundiais de reunião pela planilha do NAWS', // TODO: was changed to "Update World Committee Codes (Group IDs from NAWS) from NAWS Spreadsheet" - 'server_admin_error_no_world_ids_updated' => 'Nenhum ID mundial foi atualizado. Isso pode ser por seu usuário não ter permissão para essas reuniões', - 'server_admin_error_required_spreadsheet_column' => 'Coluna requerida no existe na planilha: ', - 'server_admin_error_bmlt_id_not_integer' => 'O ID BMLT provido não é do tipo integer: ', - 'server_admin_error_could_not_create_reader' => 'Não foi possível criar um leitor para o arquivo: ', - 'server_admin_error_no_files_uploaded' => 'Nenhum arquivo foi enviado.', - 'server_admin_error_service_bodies_already_exist' => 'Corpos de Serviço com os seguintes IDs Mundiais já existem: ', - 'server_admin_error_meetings_already_exist' => 'Reuniões com os seguintes IDs Mundiais já existem: ', - 'server_admin_ui_num_meetings_updated' => 'Numero de reuniões atualizadas: ', - 'server_admin_ui_num_meetings_not_updated' => 'Numero de reuniões que não precisam de atualização: ', - 'server_admin_ui_warning' => 'AVISO', - 'server_admin_ui_errors' => 'Erro(s)', - 'server_admin_ui_deleted_meetings_marked' => 'Number of deleted meetings marked so that they won\'t appear in future NAWS exports: ', - // TODO: re-translate this string (English version has been updated) - // 'server_admin_ui_problem_meetings' => 'reuniões foram encontradas na planilha que não existiam na base de dados. Isso pode acontecer quando uma reunião é apagada ou não publicada. Os IDs de reunião são: ', - 'server_admin_ui_problem_meetings' => 'meetings were found in the spreadsheet that couldn\'t be updated. Problem meeting IDs: ', - 'server_admin_ui_service_bodies_created' => 'Corpos de serviço criados: ', - 'server_admin_ui_meetings_created' => 'Reuniões criadas: ', - 'server_admin_ui_users_created' => 'Usuários criados: ', - 'server_admin_ui_refresh_ui_text' => 'Saia e faça novo login para ver os novos corpos de serviço, usuarios, e reuniões.', - 'import_service_bodies_and_meetings_button_text' => 'Importar corpo de serviço e reuniões', - 'import_service_bodies_and_meetings_dropdown_text' => 'Importar corpo de serviço e reuniões da exportação do NAWS (NAWS Export)', - 'server_admin_naws_import_spreadsheet_label' => 'Planilha Importada do NAWS:', - 'server_admin_naws_import_initially_publish' => 'Initialize imported meetings to \'published\': ', - 'server_admin_naws_import_explanation' => 'Uncheck the box to initialize imported meetings to \'unpublished\'. (This is useful if many of the new meetings will need to be edited or deleted, and you don\'t want them showing up in the meantime.)', - 'account_disclosure' => 'Minha conta', - 'account_name_label' => 'Nome da minha conta:', - 'account_login_label' => 'Meu login:', - 'account_type_label' => 'Eu sou:', - 'account_type_1' => 'Administrador do Servidor', - 'account_type_2' => 'Administrador de corpo de serviço', - 'ServerMapsURL' => 'https://maps.googleapis.com/maps/api/geocode/xml?address=##SEARCH_STRING##&sensor=false', - 'account_type_4' => 'Pathetic Luser Who Shouldn\'t Even Have Access to This Page -The Author of the Software Pooched it BAD!', - 'account_type_5' => 'Observador', - 'change_password_label' => 'Mude minha senha para:', - 'change_password_default_text' => 'Deixe sem preencher se não pretende mudar a senha', - 'account_email_label' => 'Meu endereço de e-mail:', - 'email_address_default_text' => 'Coloque seu e-mail', - 'account_description_label' => 'Descrição:', - 'account_description_default_text' => 'Coloque uma Descrição', - 'account_change_button_text' => 'Mude meus dados da conta', - 'account_change_fader_success_text' => 'Os dados da conta foram alterados com sucesso', - 'account_change_fader_failure_text' => 'Os dados da conta NÃO foram alterados', - 'meeting_editor_disclosure' => 'Editor de Reuniões', - 'meeting_editor_already_editing_confirm' => 'Você está atualmente editando uma reunião. Você realmente quer PERDER todas as alterações?', - 'meeting_change_fader_success_text' => 'Os dados da reunião foram alterados com sucesso', - 'meeting_change_fader_failure_text' => 'Os dados da reunião não foram alterados', - 'meeting_change_fader_success_delete_text' => 'A reunião foi removida com sucesso', - 'meeting_change_fader_fail_delete_text' => 'A reunião não foi apagada', - 'meeting_change_fader_success_add_text' => 'A nova reunião foi criada com sucesso!', - 'meeting_change_fader_fail_add_text' => 'A nova reunião NÃO foi criada...', - 'meeting_text_input_label' => 'Busque pelo texto:', - 'access_service_body_label' => 'Eu tenho acesso a:', - 'meeting_text_input_default_text' => 'Digite o texto para buscar', - 'meeting_text_location_label' => 'Isso é um local ou CEP', - 'meeting_search_weekdays_label' => 'Busca por dia da semana selecionado:', - 'meeting_search_weekdays_names' => array('Todos', 'Domingo', 'Segunda', 'Terça', 'Quarta', 'Quinta', 'Sexta', 'Sábado'), - 'meeting_search_service_bodies_label' => 'Busca pelo corpo de serviço selecionado:', - 'meeting_search_start_time_label' => 'Busca pelo horário da reunião:', - 'meeting_search_start_time_all_label' => 'Qualquer horário', - 'meeting_search_start_time_morn_label' => 'Manhã', - 'meeting_search_start_time_aft_label' => 'Tarde', - 'meeting_search_start_time_eve_label' => 'Noite', - 'meeting_search_no_results_text' => 'Nenhuma reunião encontrada', - 'meeting_editor_tab_specifier_text' => 'Busca por reuniões', - 'meeting_editor_tab_editor_text' => 'Editar Reuniões', // TODO: change to 'Edit Or Create Meetings' - 'meeting_editor_create_new_text' => 'Criar Nova Reunião', - 'meeting_editor_location_map_link' => 'Localização no Mapa', - 'meeting_editor_screen_match_ll_button' => 'Configure Longitude e Latitude do Endereço', - 'meeting_editor_screen_default_text_prompt' => 'Coloque um texto ou numero', - 'meeting_is_published' => 'Reunião está publicada', - 'meeting_unpublished_note' => 'Nota: Despublicar uam reunião indica que estátemporariamente fechada. Se ela está permanentemente fechada, por favor a delete.', - 'meeting_editor_screen_meeting_name_label' => 'Nome da Reunião:', - 'meeting_editor_screen_meeting_name_prompt' => 'Coloque o nome da reunião', - 'meeting_editor_screen_meeting_weekday_label' => 'Dia da Semana:', - 'meeting_editor_screen_meeting_start_label' => 'Horário de ínicio da Reunião:', - 'meeting_editor_screen_meeting_time_zone_label' => 'Meeting Time Zone:', - 'meeting_editor_screen_meeting_am_label' => 'AM', - 'meeting_editor_screen_meeting_pm_label' => 'PM', - 'meeting_editor_screen_meeting_noon_label' => 'Meio-Dia', - 'meeting_editor_screen_meeting_midnight_label' => 'Meia-Noite', - 'meeting_editor_screen_meeting_duration_label' => 'Duration:', - 'meeting_editor_screen_meeting_oe_label' => 'Aberta até o final', - 'meeting_editor_screen_meeting_cc_label' => 'Código do Comitê Mundial:', - 'meeting_editor_screen_meeting_cc_advice' => 'Normally leave this field alone (see documentation).', // TODO: translate - 'meeting_editor_screen_meeting_contact_label' => 'Contato por e-mail:', - 'meeting_editor_screen_meeting_contact_prompt' => 'Contato por e-mail apenas para essa reunião', - 'meeting_editor_screen_meeting_sb_label' => 'Corpo de Serviço:', - 'meeting_editor_screen_meeting_sb_default_value' => 'Nenhum Corpo de Serviço selecionado', - 'meeting_editor_screen_meeting_longitude_label' => 'Longitude:', - 'meeting_editor_screen_meeting_longitude_prompt' => 'Coloque a Longitude', - 'meeting_editor_screen_meeting_latitude_label' => 'Latitude:', - 'meeting_editor_screen_meeting_latitude_prompt' => 'Coloque a Latitude', - 'meeting_editor_screen_meeting_location_label' => 'Referência:', - 'meeting_editor_screen_meeting_location_prompt' => 'Coloque uma referência (exemplo: nome do prédio)', - 'meeting_editor_screen_meeting_info_label' => 'Informação Extra:', - 'meeting_editor_screen_meeting_info_prompt' => 'Coloque aqui informações como Carimbo para beneficiários da Justiça ou outras informaçẽos relevantes', - 'meeting_editor_screen_meeting_street_label' => 'Nome da Rua ou Avenida:', - 'meeting_editor_screen_meeting_street_prompt' => 'Coloque aqui o endereço da entrada do grupo', - 'meeting_editor_screen_meeting_neighborhood_label' => 'Bairro:', - 'meeting_editor_screen_meeting_neighborhood_prompt' => 'Coloque aqui o nome do Bairro', - 'meeting_editor_screen_meeting_borough_label' => 'região da cidade(por exemplo zona leste ou centro)', - 'meeting_editor_screen_meeting_borough_prompt' => 'Coloque aqui a região (não é obrigatório)', - 'meeting_editor_screen_meeting_city_label' => 'Nome da Cidade:', - 'meeting_editor_screen_meeting_city_prompt' => 'Nome da Cidade', - 'meeting_editor_screen_meeting_county_label' => 'Região do País:', - 'meeting_editor_screen_meeting_county_prompt' => 'Coloque aqui a região do país (exemplo Região Norte, Nordeste, Sudeste, etc)', - 'meeting_editor_screen_meeting_state_label' => 'Estado:', - 'meeting_editor_screen_meeting_state_prompt' => 'Coloque aqui o nome do Estado', - 'meeting_editor_screen_meeting_zip_label' => 'CEP:', - 'meeting_editor_screen_meeting_zip_prompt' => 'Coloque aqui o CEP sem hífen (exemplo 9876500)', - 'meeting_editor_screen_meeting_nation_label' => 'País:', - 'meeting_editor_screen_meeting_nation_prompt' => 'nome do país', - 'meeting_editor_screen_meeting_comments_label' => 'Comentários:', - 'meeting_editor_screen_meeting_train_lines_label' => 'Linhas de trêm ou metrô:', - 'meeting_editor_screen_meeting_bus_lines_label' => 'Linhas de ônibus:', - 'meeting_editor_screen_meeting_phone_meeting_number_label' => 'Phone Meeting Dial-in Number:', - 'meeting_editor_screen_meeting_phone_meeting_number_prompt' => 'Enter the dial-in number for a phone or virtual meeting', - 'meeting_editor_screen_meeting_virtual_meeting_link_label' => 'Virtual Meeting Link:', - 'meeting_editor_screen_meeting_virtual_meeting_link_prompt' => 'Enter the link for a virtual meeting', - 'meeting_editor_screen_meeting_virtual_meeting_additional_info_label' => 'Virtual Meeting Additional Information:', - 'meeting_editor_screen_meeting_virtual_meeting_additional_info_prompt' => 'Enter any additional information for joining the virtual meeting, including directly from the app. For example, if the meeting uses Zoom, "Zoom ID: 456 033 8613, Passcode: 1953" would be appropriate.', - 'meeting_editor_screen_meeting_venue_type' => 'Venue Type:', - 'meeting_editor_screen_meeting_venue_type_inperson' => 'In-Person', - 'meeting_editor_screen_meeting_venue_type_virtual' => 'Virtual', - 'meeting_editor_screen_meeting_venue_type_virtualTC' => 'Virtual (temporarily replacing an in-person)', - 'meeting_editor_screen_meeting_venue_type_hybrid' => 'Hybrid (both in-person and virtual)', - 'meeting_editor_screen_meeting_venue_type_validation' => 'You must select a venue type.', - 'meeting_editor_screen_meeting_virtual_info_missing' => 'Virtual or hybrid meetings must have a Virtual Meeting Link, a Phone Meeting Dial-in Number, or Virtual Meeting Additional Information', - 'meeting_editor_screen_meeting_location_warning' => 'Meeting should have a location (at least a city/town and state/province, or a zip/postal code).', - 'meeting_editor_screen_meeting_address_warning' => 'In-person or hybrid meetings should have a street address.', - 'meeting_editor_screen_meeting_url_validation' => 'Virtual Meeting Link is not a valid URL.', - 'meeting_editor_screen_meeting_url_or_phone_warning' => 'Virtual or hybrid meetings should have either a Virtual Meeting Link or a Phone Meeting Dial-in Number', - 'meeting_editor_screen_meeting_additional_warning' => 'Please also fill in Virtual Meeting Additional Information if there is a Virtual Meeting Link.', - 'meeting_editor_screen_in_person_virtual_info_warning' => 'In-person meetings shouldn\'t have any virtual meeting information.', - 'meeting_editor_screen_meeting_virtual_location_info_warning' => 'Virtual meetings shouldn\'t have a location name or address.', - 'meeting_editor_screen_meeting_validation_warning' => 'There are warnings. Are you sure you want to save anyway? If not, press \'cancel\' and go to the Location tab to see the warnings in place and address them.', - 'meeting_editor_screen_meeting_validation_failed' => 'Unable to save due to input errors. Please go to the Location tab to address them, and then retry saving. Errors: ', - 'meeting_editor_screen_meeting_validation_warnings' => 'Input warnings shown on the Location tab: ', - 'meeting_editor_screen_meeting_contact_name_1_label' => 'Nome para contato:', - 'meeting_editor_screen_meeting_contact_email_1_label' => 'E-mail de contato:', - 'meeting_editor_screen_meeting_contact_phone_1_label' => 'Telefone de contato:', - 'meeting_editor_screen_meeting_contact_name_2_label' => 'Nome para contato:', - 'meeting_editor_screen_meeting_contact_email_2_label' => 'E-mail de contato:', - 'meeting_editor_screen_meeting_contact_phone_2_label' => 'Telefone de contato:', - 'meeting_editor_screen_meeting_publish_search_prompt' => 'Busque por:', - 'meeting_editor_screen_meeting_publish_search_pub' => 'Apenas reuniões publicadas', - 'meeting_editor_screen_meeting_publish_search_unpub' => 'Apenas reuniões não publicadas', - 'meeting_editor_screen_meeting_visibility_advice' => 'Isso não aparecera na pesquisa .', - 'meeting_editor_screen_meeting_publish_search_all' => 'Todas as reuniões', - 'meeting_editor_screen_meeting_create_button' => 'Criar nova Reunião', - 'meeting_editor_screen_delete_button' => 'Apagar essa reunião', - 'meeting_editor_screen_delete_button_confirm' => 'Tem certeza que quer apagar essa reunião?', - 'meeting_editor_screen_cancel_button' => 'Cancelar', - 'logout' => 'SAIR', - 'meeting_editor_screen_cancel_confirm' => 'Tem certeza que vai cancelar essa edição de reunião? Todas as alterações serão perdidas?', - 'meeting_lookup_failed' => 'A localização do endereço falhou', - 'meeting_lookup_failed_not_enough_address_info' => 'Não há informações suficientes para buscar o endereço.', - 'meeting_create_button_name' => 'Salvar como uma nova reunião', - 'meeting_saved_as_a_copy' => 'Salvar uma CÓPIA dessa reunião (Criando como uma nova reunião)', - 'meeting_save_buttonName' => 'Salvar as alterações dessa reunião', - 'meeting_editor_tab_bar_basic_tab_text' => 'Básico', - 'meeting_editor_tab_bar_location_tab_text' => 'Localização', - 'meeting_editor_tab_bar_format_tab_text' => 'Formato', - 'meeting_editor_tab_bar_other_tab_text' => 'Outros', - 'meeting_editor_tab_bar_history_tab_text' => 'Histórico', - 'meeting_editor_result_count_format' => '%d Reuniões encontradas', - 'meeting_id_label' => 'ID da reunião:', - 'meeting_editor_default_zoom' => '13', - 'meeting_editor_default_weekday' => '2', - 'meeting_editor_default_start_time' => '20:30:00', - 'login_banner' => 'Ferramenta Básica de Lista de Reuniões BMLT', - 'login_underbanner' => 'Console de Administração do servidor', - 'login' => 'ID de acesso', - 'password' => 'Senha', - 'button' => 'ENTRAR', - 'cookie' => 'Ativar os cookies do navegador para administrar esse servidor.', - 'noscript' => 'Você não vai conseguir administrar esse servidor sem JavaScript.', - 'title' => 'Por favor fazer login para administrar o servidor.', - 'edit_Meeting_object_not_found' => 'ERRO: A Reunião não foi encontrada.', - 'edit_Meeting_object_not_changed' => 'ERRO: A Reunião não foi alterada.', - 'edit_Meeting_auth_failure' => 'Você não tem permissão para editar essa reunião.', - 'not_auth_1' => 'NÃO ALTORIZADO', - 'not_auth_2' => 'Você não tem permissão para editar esse servidor.', - 'not_auth_3' => 'Problema com usuário ou senha usado.', - 'email_format_bad' => 'Verifique se o e-mail está correto.', - 'history_header_format' => '
%sby %s
', - 'history_no_history_available_text' => '

No History Available For This Meeting

', - 'service_body_editor_disclosure' => 'Administração de Corpo de Serviço', - 'service_body_change_fader_success_text' => 'As configurações de Corpo de Serviço foram alteradas com sucesso', - 'service_body_change_fader_fail_text' => 'Falha na configuração de Corpo de Serviço', - 'service_body_editor_screen_sb_id_label' => 'ID:', - 'service_body_editor_screen_sb_name_label' => 'Nome:', - 'service_body_name_default_prompt_text' => 'Coloque aqui o nome da estrutura de serviço', - 'service_body_parent_popup_label' => 'Estrutura de Serviço Responsável:', - 'service_body_parent_popup_no_parent_option' => 'Estrutura de Serviço Líder', - 'service_body_editor_screen_sb_admin_user_label' => 'Administrador Primário:', - 'service_body_editor_screen_sb_admin_description_label' => 'Descrição:', - 'service_body_description_default_prompt_text' => 'Coloque aqui a descrição da estrutura de serviço', - 'service_body_editor_screen_sb_admin_email_label' => 'Email de contato:', - 'service_body_email_default_prompt_text' => 'E-mail de contato da estrutura', - 'service_body_editor_screen_sb_admin_uri_label' => 'site da estrutura:', - 'service_body_uri_default_prompt_text' => 'Coloque aqui o site da estrutura de serviço', - 'service_body_editor_screen_sb_admin_full_editor_label' => 'Lista de editores da estrutura:', - 'service_body_editor_screen_sb_admin_full_editor_desc' => 'Esses usuários tem acesso completo a edição das reuniões da estrutura.', - 'service_body_editor_screen_sb_admin_editor_label' => 'Editores básicos da lista:', - 'service_body_editor_screen_sb_admin_editor_desc' => 'Esses usuários podem acessar somente reuniões não publicadas.', - 'service_body_editor_screen_sb_admin_observer_label' => 'Observadores:', - 'service_body_editor_screen_sb_admin_observer_desc' => 'Esses usuários só podem ver os dados, não edita-los.', - 'service_body_dirty_confirm_text' => 'Você alterou os dados dessa estrutura. Saindo perderá todas as mudanças. Tem certeza?', - 'service_body_save_button' => 'Salvar alterações', - 'service_body_create_button' => 'Criar esse corpo de serviço', - 'service_body_delete_button' => 'Apagar esse corpo de serviço', - 'service_body_delete_perm_checkbox' => 'Apagar esse corpo de serviço permanentemente.', - 'service_body_delete_button_confirm' => 'Tem certeza que quer apagar esse corpo de serviço? Tenha certeza de apagar as reuniões ou transferi-las para outro corpo de serviço antes de continuar.', - 'service_body_delete_button_confirm_perm' => 'Este corpo de serviço será apagado permanentemente!', - 'service_body_change_fader_create_success_text' => 'A estrutura de serviço foi criada com sucesso', - 'service_body_change_fader_create_fail_text' => 'Houve falha na criação da estrutura de serviço', - 'service_body_change_fader_delete_success_text' => 'A estrutura de serviço foi apagada', - 'service_body_change_fader_delete_fail_text' => 'Houve falha ao apagar a estrutura de serviço', - 'service_body_change_fader_fail_no_data_text' => 'A alteração da estrutura de serviço falhou, Por não haver dados fornecidos', - 'service_body_change_fader_fail_cant_find_sb_text' => 'Falha na alteração da estrutura de serviço, Estrutura de serviço não encontrada', - 'service_body_change_fader_fail_cant_update_text' => 'Falha na alteração da estrutura de serviço, Estrutura de serviço não atualizada', - 'service_body_change_fader_fail_bad_hierarchy' => 'Falha na alteração da estrutura de serviço', - 'service_body_cancel_button' => 'Restaurar ao original', - 'service_body_editor_type_label' => 'Tipo de Estrutura de Serviço:', - 'service_body_editor_type_c_comdef_service_body__GRP__' => 'Grupo', - 'service_body_editor_type_c_comdef_service_body__COP__' => 'Operador', - 'service_body_editor_type_c_comdef_service_body__ASC__' => 'CSA Comitê de Serviço de Área', - 'service_body_editor_type_c_comdef_service_body__RSC__' => 'CSR Comitê de Serviço da Região', - 'service_body_editor_type_c_comdef_service_body__WSC__' => 'Conferẽncia Mundial de Serviço', - 'service_body_editor_type_c_comdef_service_body__MAS__' => 'Área Metropolitana', - 'service_body_editor_type_c_comdef_service_body__ZFM__' => 'Forum Zonal', - 'service_body_editor_type_c_comdef_service_body__GSU__' => 'Grupo de Unidade de Serviço', - 'service_body_editor_type_c_comdef_service_body__LSU__' => 'Unidade de Serviço Local', - 'service_body_editor_screen_helpline_label' => 'Linha de Ajuda:', - 'service_body_editor_screen_helpline_prompt' => 'Coloque aqui o numero do Linha de Ajuda', - 'service_body_editor_uri_naws_format_text' => 'Busque as reuniões dessa estrutura de serviço em arquivo no formato compatível com o NAWS', - 'edit_Meeting_meeting_id' => 'ID da Reunião:', - 'service_body_editor_create_new_sb_option' => 'Criar uma nova estrutura de serviço', - 'service_body_editor_screen_world_cc_label' => 'Código do Comitê Mundial:', - 'service_body_editor_screen_world_cc_prompt' => 'Coloque aqui o código do Comitê Mundial', - 'user_editor_disclosure' => 'Usuário Administrador', - 'user_editor_create_new_user_option' => 'Criar um novo usuário', - 'user_editor_screen_sb_id_label' => 'ID:', - 'user_editor_account_login_label' => 'Login:', - 'user_editor_login_default_text' => 'nome de usuário', - 'user_editor_account_type_label' => 'O usuário é:', - 'user_editor_user_owner_label' => 'Pertence a: ', - 'user_editor_account_type_1' => 'Administrador do servidor', - 'user_editor_account_type_2' => 'Administrador da estrutura de serviço', - 'user_editor_account_type_3' => 'Editor de Estrutura de Serviço', - 'user_editor_account_type_5' => 'Observador', - 'user_editor_account_type_4' => 'Usuário desativado', - 'user_editor_account_name_label' => 'Nome de usuário:', - 'user_editor_name_default_text' => 'Coloque o usuário aqui', - 'user_editor_account_description_label' => 'Descrição:', - 'user_editor_description_default_text' => 'Coloque aqui a descrição do usuário', - 'user_editor_account_email_label' => 'Email:', - 'user_editor_email_default_text' => 'coloque aqui o e-mail', - 'user_change_fader_success_text' => 'Alteração do usuário realizada com sucesso', - 'user_change_fader_fail_text' => 'Falha na alteração do usuário', - 'user_change_fader_create_success_text' => 'Usuário criado com sucesso!', - 'user_change_fader_create_fail_text' => 'Falha na criação do usuário', - 'user_change_fader_create_fail_already_exists' => 'Você está tentando criar um usuário que já existe.', - 'user_change_fader_delete_success_text' => 'Usuário apagado com sucesso', - 'user_change_fader_delete_fail_text' => 'Falha ao apagar usuário', - 'user_save_button' => 'Salvar alterações para esse usuário', - 'user_create_button' => 'Criar novo usuário', - 'user_cancel_button' => 'Restaurar ao Original', - 'user_delete_button' => 'Apagar esse usuário', - 'user_delete_perm_checkbox' => 'Apagar permanentemente o usuário', - 'user_password_label' => 'Mudar Senha para:', - 'user_new_password_label' => 'Senha alterada:', - 'user_password_default_text' => 'Deixe em branco, a não ser que queira mudar a senha', - 'user_new_password_default_text' => 'Você deve configurar uma senha para o novo usuário', - 'user_dirty_confirm_text' => 'Você fez alterações para esse uusuário. Tem certeza que quer perder as alteraçẽos feitas?', - 'user_delete_button_confirm' => 'Tem certeza que vai apagar o usuário?', - 'user_delete_button_confirm_perm' => 'Esse usuário vai ser apagado permanentemente!', - 'user_create_password_alert_text' => 'Novos usuários devem ter uma senha. Você não digitou uma senha ainda.', - 'user_change_fader_fail_no_data_text' => 'Falha na alteração de usuário, Não há dados fornecidos', - 'user_change_fader_fail_cant_find_sb_text' => 'Falha na alteração do usuário, Usuario não existe', - 'user_change_fader_fail_cant_update_text' => 'Falha na alteração do usuário, Usuário não atualizado', - 'format_editor_disclosure' => 'Administração do Formato de Reunião', - 'format_change_fader_change_success_text' => 'Formato de Reunião atualizado', - 'format_change_fader_change_fail_text' => 'Falha na atualização de formato', - 'format_change_fader_create_success_text' => 'Formato de Reunião criado com sucesso', - 'format_change_fader_create_fail_text' => 'Falha na criação de Formato de Reunião', - 'format_change_fader_delete_success_text' => 'Formato apagado com sucesso', - 'format_change_fader_delete_fail_text' => 'Falha ao apagar formato', - 'format_change_fader_fail_no_data_text' => 'Falha na alteração de formato, falta de dados fornecidos', - 'format_change_fader_fail_cant_find_sb_text' => 'Falha na alteração de formato, formato não encontrado', - 'format_change_fader_fail_cant_update_text' => 'Falha na alteração de formato, formato não atualizado', - 'format_editor_name_default_text' => 'Coloque uma breve descrição', - 'format_editor_description_default_text' => 'Coloque aqui uma descrição mais detalhada', - 'format_editor_create_format_button_text' => 'Criar novo formato', - 'format_editor_cancel_create_format_button_text' => 'Cancelar', - 'format_editor_create_this_format_button_text' => 'Criar formato', - 'format_editor_change_format_button_text' => 'Alterar formato', - 'format_editor_delete_format_button_text' => 'Apagar formato', - 'format_editor_reset_format_button_text' => 'Restaurar ao Original', - 'need_refresh_message_fader_text' => 'Você deve atualizar essa pagina antes de fazer novas alterações (F5)', - 'need_refresh_message_alert_text' => 'Pelas alterações feitas na Administração do Servidor, Administração de Estrutura de Serviço, Administração de Usuário, ou Administração de Formato de Reunião, as informações demonstradas nessa sessão não são mais precisas, então essa pagina precisa ser ATUALIZADA. Para isso basta teclar a tecla de função F5 ou sair e logar novamente.', - 'format_editor_delete_button_confirm' => 'Tem certeza que deseja apagar esse Formato de Reunião?', - 'format_editor_delete_button_confirm_perm' => 'Esse formato será apagado permanentemente!', - 'format_editor_missing_key' => 'This format should have an entry for every language (at least a key).', // TODO: translate - 'format_editor_reserved_key' => 'This key is reserved for a venue type format - please use something different.', // TODO: translate - 'min_password_length_string' => 'Senha muito curta! Ela tem que ter no mínimo %d caracteres!', - 'AJAX_Auth_Failure' => 'Falha de autorização para essa ação. Falha de configuração do servidor.', - 'Maps_API_Key_Warning' => 'Há um problema com a chave da API do Google Maps.', - 'Maps_API_Key_Not_Set' => 'A chave da API do Google Maps não foi configurada.', - 'Observer_Link_Text' => 'Meeting Browser', - 'Data_Transfer_Link_Text' => 'Importar Dados de Reuniões (AVISO: Isso vai sobreescrever os dados atuais!)', - 'MapsURL' => 'https://maps.google.com/maps?q=##LAT##,##LONG##+(##NAME##)&ll=##LAT##,##LONG##', - 'hidden_value' => 'Não pode mostrar dados -não autorizado', - 'Value_Prompts' => array( - 'id_bigint' => 'Meeting ID', - 'worldid_mixed' => 'World Services ID', - 'service_body' => 'Estrutura de Serviço', - 'service_bodies' => 'Service Bodies', - 'weekdays' => 'Dia da Semana', - 'weekday' => 'Reunião acontece a cada', - 'start_time' => 'Horário de ínicio', - 'duration_time' => 'Duração da Reunião', - 'location' => 'Localidade', - 'duration_time_hour' => 'Hora', - 'duration_time_hours' => 'Horas', - 'duration_time_minute' => 'Minuto', - 'duration_time_minutes' => 'Minutos', - 'lang_enum' => 'Língua', - 'formats' => 'Formato', - 'distance' => 'Distancia do Centro', - 'generic' => 'Reunião de NA', - 'close_title' => 'Fechar detalhes da Reunião', - 'close_text' => 'Fechar janela', - 'map_alt' => 'Mapa de reuniões', - 'map' => 'Clique aqui para abrir o mapa', - 'title_checkbox_unpub_meeting' => 'Essa Reunião não foi publicada. Não pode ser pesquisada.', - 'title_checkbox_copy_meeting' => 'Esta reunião é uma duplicata e também não foi publicada. Não pode ser encontrada numa pesquisa.' - ), - 'world_format_codes_prompt' => 'Formato NAWS:', - 'world_format_codes' => array( - '' => 'Nenhum', - 'OPEN' => 'Aberta', - 'CLOSED' => 'Fechada', - 'WCHR' => 'Acessivel à Cadeirante', - 'BEG' => 'Recém-Chegados', - 'BT' => 'Texto Básico', - 'CAN' => 'Luz de Velas', - 'CPT' => '12 Conceitos', - 'CW' => 'Crianças bem vindas', - 'DISC' => 'Partilha', - 'GL' => 'LGBTQ+', - 'IP' => 'Estudo de IPs', - 'IW' => 'Estudo Isto Resulta', - 'JFT' => 'Estudo do Só Por Hoje', - 'LC' => 'Estudo Vivendo Limpo', - 'LIT' => 'Estudo de Literatura', - 'M' => 'Só Homens', - 'MED' => 'Meditação', - 'NS' => 'Proibido Fumar', - 'QA' => 'Perguntas e Respostas', - 'RA' => 'Acesso Restrito', - 'S-D' => 'Speaker/Discussion', // TODO translate - 'SMOK' => 'Permitido Fumar', - 'SPK' => 'Temática', - 'STEP' => 'Passos', - 'SWG' => 'Estudo Guia de Passos', - 'TOP' => 'Tema', - 'TRAD' => 'Tradições', - 'VAR' => 'Formato Variável', - 'W' => 'Só Mulheres', - 'Y' => 'Só Jovens', - 'LANG' => 'Lingua Estrangeira', - 'GP' => 'Guia de Principios', - 'NC' => 'Não permite crianças', - 'CH' => 'Fechado em feriados', - 'VM' => 'Virtual', // TODO translate - 'HYBR' => 'Virtual and In-Person', // TODO translate - 'TC' => 'Temporarily Closed Facility', // TODO translate - 'SPAD' => 'Spiritual Principle a Day', // TODO translate - ), - 'format_type_prompt' => 'Format Type:', - 'format_type_codes' => array( - '' => 'Nenhum', - 'FC1' => 'Formato de Reunião (Estudo de literatura, Temática, etc.)', - 'FC2' => 'Caracteristica do local (Acessivel a Cadeirante, Estacionamento limitado, etc.)', - 'FC3' => 'Necessidades e Restrições (Só Mulheres, LGTBQ+, Crianças não permitidas, etc.)', - 'O' => 'Atenção não membros (Abertas ou Fechadas)', - 'LANG' => 'Lingua', - 'ALERT' => 'Formato ()', - ), - - 'cookie_monster' => 'Este site usa cookies para ajudar na escolha da sua lingua padrão.', - 'main_prompts' => array( - 'id_bigint' => 'ID', - 'worldid_mixed' => 'ID Mundial', - 'shared_group_id_bigint' => 'Unused', - 'service_body_bigint' => 'ID Estrutura de Serviço', - 'weekday_tinyint' => 'Dia da Semana', - 'venue_type' => 'Venue Type', - 'start_time' => 'Horário', - 'duration_time' => 'Duração', - 'time_zone' => 'Time Zone', - 'formats' => 'Formatos', - 'lang_enum' => 'Lingua', - 'longitude' => 'Longitude', - 'latitude' => 'Latitude', - 'published' => 'Publicada', - 'email_contact' => 'Contato Email', - ), - 'check_all' => 'Marque Todas', - 'uncheck_all' => 'Desmarque Todas', - 'automatically_calculated_on_save' => 'Calcular automaticamente ao salvar.' -); - -$email_contact_strings = array( - 'meeting_contact_form_subject_format' => "[MEETING LIST CONTACT] %s", - 'meeting_contact_message_format' => "%s\n--\nThis message concerns the meeting named \"%s\", which meets at %s, on %s.\nBrowser Link: %s\nEdit Link: %s\nIt was sent directly from the meeting list web server, and the sender is not aware of your email address.\nPlease be aware that replying will expose your email address.\nIf you use \"Reply All\", and there are multiple email recipients, you may expose other people's email addresses.\nPlease respect people's privacy and anonymity; including the original sender of this message." -); - -$change_type_strings = array( - '__THE_MEETING_WAS_CHANGED__' => 'Reunião Alterada.', - '__THE_MEETING_WAS_CREATED__' => 'Reunião foi criada.', - '__THE_MEETING_WAS_DELETED__' => 'Reunião foi apagada.', - '__THE_MEETING_WAS_ROLLED_BACK__' => 'Restaurada a versão anterior da reunião.', - - '__THE_FORMAT_WAS_CHANGED__' => 'O Formato foi alterado.', - '__THE_FORMAT_WAS_CREATED__' => 'O Formato foi criado.', - '__THE_FORMAT_WAS_DELETED__' => 'O formato foi apagado.', - '__THE_FORMAT_WAS_ROLLED_BACK__' => 'Restaurado o formato anterior da reunião.', - - '__THE_SERVICE_BODY_WAS_CHANGED__' => 'A estrutura de serviço foi alterada.', - '__THE_SERVICE_BODY_WAS_CREATED__' => 'A estrutura de serviço foi criada.', - '__THE_SERVICE_BODY_WAS_DELETED__' => 'A estrutura de serviço foi apagada.', - '__THE_SERVICE_BODY_WAS_ROLLED_BACK__' => 'Restaurada a estrutura de serviço anterior.', - - '__THE_USER_WAS_CHANGED__' => 'O usuário foi alterado.', - '__THE_USER_WAS_CREATED__' => 'O usuário foi criado.', - '__THE_USER_WAS_DELETED__' => 'O usuário foi apagado.', - '__THE_USER_WAS_ROLLED_BACK__' => 'Restaurado o usuário para versão anterior.', - - '__BY__' => 'por', - '__FOR__' => 'para' -); - -$detailed_change_strings = array( - 'was_changed_from' => 'mudou de', - 'to' => 'para', - 'was_changed' => 'foi alterado', - 'was_added_as' => 'adicionado como', - 'was_deleted' => 'foi apagado', - 'was_published' => 'A Reunião foi publicada', - 'was_unpublished' => 'A Reunião foi tirada do ar', - 'formats_prompt' => 'O Formato da Reunião', - 'duration_time' => 'Duração da Reunião', - 'start_time' => 'Inicio da Reunião', - 'longitude' => 'Longitude da Reunião', - 'latitude' => 'Latitude da Reunião', - 'sb_prompt' => 'A reunião alterou sua estrutura de serviço de', - 'id_bigint' => 'ID da reunião', - 'lang_enum' => 'Idioma da Reunião', - 'worldid_mixed' => 'The World Committee Code', - 'weekday_tinyint' => 'The day of the week on which the meeting gathers', - 'non_existent_service_body' => 'Estrutura de Serviço não existe mais', -); - -defined('_END_CHANGE_REPORT') or define('_END_CHANGE_REPORT', '.'); diff --git a/src/legacy/local_server/server_admin/lang/ru/data_transfer_strings.php b/src/legacy/local_server/server_admin/lang/ru/data_transfer_strings.php deleted file mode 100644 index c78bf7dc4..000000000 --- a/src/legacy/local_server/server_admin/lang/ru/data_transfer_strings.php +++ /dev/null @@ -1,45 +0,0 @@ -.*/ - defined('BMLT_EXEC') or die('Cannot Execute Directly'); // Makes sure that this file is in the correct context. - - $comdef_data_transfer_strings = array ( 'key_strings' => array ( 'id_bigint' => 1, - 'worldid_mixed' => 1, - 'shared_group_id_bigint' => 1, - 'service_body_bigint' => 1, - 'weekday_tinyint' => 1, - 'start_time' => 1, - 'duration_time' => 1, - 'formats' => 1, - 'lang_enum' => 1, - 'longitude' => 1, - 'latitude' => 1, - 'published' => 1, - 'email_contact' => 1 - ), - - 'days' => array ( 'Воскресенье', - 'Понедельник', - 'Вторник', - 'Среда', - 'Четверг', - 'Пятница', - 'Суббота' - ), - ); diff --git a/src/legacy/local_server/server_admin/lang/ru/install_wizard_strings.php b/src/legacy/local_server/server_admin/lang/ru/install_wizard_strings.php deleted file mode 100644 index e23847b23..000000000 --- a/src/legacy/local_server/server_admin/lang/ru/install_wizard_strings.php +++ /dev/null @@ -1,161 +0,0 @@ -.*/ -defined('BMLT_EXEC') or die('Cannot Execute Directly'); // Makes sure that this file is in the correct context. - -global $comdef_install_wizard_strings; - -$comdef_install_wizard_strings = array ( - 'Database_Version_Error' => 'ОШИБКА: на этом сервере должен быть установлен PHP версии 5.6 или выше!', - 'Database_PDO_Error' => 'ОШИБКА: у вас не установлен PHP PDO!', - 'Database_Type_Error' => 'ОШИБКА: даже если у вас есть PDO, у вас не установлены драйверы базы данных!', - 'Database_Type_MySQL_Error' => 'ОШИБКА: Даже если у вас есть PDO и у вас установлены драйверы баз данных, ни один из них не является MySQL (единственный поддерживаемый драйвер)!', - 'Database_TestButton_Text' => 'ТЕСТ', - 'Database_TestButton_Success' => 'Соединение с базой данных прошло успешно.', - 'Database_TestButton_Fail' => 'Ошибка подключения к базе данных: ', - 'Database_TestButton_Fail2' => 'Не удалось подключиться к базе данных, поскольку уже существует инициализированная база данных.', - 'Database_Whitespace_Note' => 'Warning: %s has whitespace at the beginning or end.', - - 'AJAX_Handler_DB_Connect_Error' => 'Ошибка подключения к базе данных! Убедитесь, что база данных существует, ПОЛНОСТЬЮ ПУСТАЯ, пользователь создан, и этот пользователь имеет полные права доступа к пустой базе данных.', - 'AJAX_Handler_DB_Established_Error' => 'База данных уже существует и была настроена! Вы не можете использовать эту настройку, чтобы перезаписать существующую базу данных!', - 'AJAX_Handler_DB_Incomplete_Error' => 'Не достаточно информации для инициализации базы!', - - 'NoDatabase_Note_AlreadySet' => 'База данных уже инициализирована с указанным префиксом таблицы. Пожалуйста, выберите новую.', - 'NoDatabase_Note_GenericError' => 'При подключении к базе данных произошла ошибка. Пожалуйста, проверьте настройки вашей базы данных.', - 'NoDatabase_Note_ClickHere' => 'Нажмите здесь, чтобы вернуться на страницу настройки базы данных.', - 'NoDatabase_Note_PasswordIssue' => 'Вы должны выбрать имя пользователя и пароль для пользователя Администратора сервера.', - 'NoDatabase_Note_ServerSettings_ClickHere' => 'Нажмите здесь, чтобы вернуться на страницу настроек сервера.', - 'NoServerAdmin_Note_AlreadySet' => 'База данных уже существует, поэтому вы не можете настроить учетную запись администратора сервера (одна из них уже существует).', - 'NeedLongerPasswordNote' => 'Этот пароль слишком короткий. Этот пароль должен быть не менее % символов.', - - 'Prev_Button' => 'Предыдущий', - 'Next_Button' => 'Следущий', - - 'Page_1_Tab' => 'ШАГ 1: База данных', - 'Page_1_Heading' => 'Настройки подключения к базе данных', - 'Page_1_Text' => 'Прежде чем вы сможете применить настройки на этой странице, вы должны настроить новую ПОЛНОСТЬЮ ПУСТУЮ базу данных и создать пользователя базы данных, который имеет полные права пользователя в этой базе данных.', - - 'Database_Name' => 'Имя базы данных:', - 'Database_Name_Default_Text' => 'Введите имя базы данных', - 'Database_Type' => 'Тип базы данных:', - 'Database_Host' => 'Хост базы данных:', - 'Database_Host_Default_Text' => 'Введите хост базы данных', - 'Database_Host_Additional_Text' => 'Это обычно "localhost."', - 'Table_Prefix' => 'Префикс таблицы:', - 'Table_Prefix_Default_Text' => 'Введите префикс таблицы', - 'Table_Prefix_Additional_Text' => 'Только для нескольких root серверов, совместно использующих базу данных.', - 'Database_User' => 'Пользователь базы данных:', - 'Database_User_Default_Text' => 'Введите имя пользователя базы данных', - 'Database_PW' => 'Пароль базы данных:', - 'Database_PW_Default_Text' => 'Введите пароль базы данных', - 'Database_PW_Additional_Text' => 'Сделайте самый уродливый, сложный пароль. Он обладает огромной силой, потому что вы не сможете его запомнить.', - - 'Maps_API_Key_Warning' => 'Возникла проблема с ключом API Карт Google.', - 'Maps_API_Key_Not_Set' => 'Ключ API Карт Google не задан.', - 'Maps_API_Key_Valid' => 'Ключ API Карт Google действителен.', - 'Maps_API_Key_ClickHere' => 'Нажмите здесь, чтобы вернуться на страницу настройки ключа API Карт Google.', - - 'Page_2_Tab' => 'ШАГ 2: Настройки API Карт Google', - 'Page_2_Heading' => 'Настройки API Карт Google', - 'Page_2_API_Key_Prompt' => 'Введите ключ API Google для геокодирования:', - 'Page_2_API_Key_Set_Button' => 'ТЕСТОВЫЙ КЛЮЧ', - 'Page_2_API_Key_Not_Set_Prompt' => 'Сначала установите API ключ', - 'Page_2_Text' => 'При сохранении собрания корневой сервер BMLT использует API Карт Google для определения широты и долготы для адреса встречи. Эти настройки необходимы для того, чтобы корневой сервер BMLT мог взаимодействовать с API Карт Google.', - - 'Page_3_Tab' => 'ШАГ 3: Настройки сервера', - 'Page_3_Heading' => 'Установить различные глобальные настройки сервера', - 'Page_3_Text' => 'Это несколько параметров, которые влияют на администрирование и общую конфигурацию этого сервера. Большинство настроек сервера выполняются на самом сервере.', - 'Admin_Login' => 'Логин администратора сервера:', - 'Admin_Login_Default_Text' => 'Введите логин администратора сервера', - 'Admin_Login_Additional_Text' => 'Это строка логина для Администратора Сервера.', - 'Admin_Password' => 'Пароль администратора сервера:', - 'Admin_Password_Default_Text' => 'Введите пароль администратора сервера', - 'Admin_Password_Additional_Text' => 'Убедитесь, что это нетривиальный пароль! У этого есть большая сила! (Вы никогда не сможете его запомнить).', - 'ServerAdminName' => 'Администратор Сервера', - 'ServerAdminDesc' => 'Главный администратор сервера', - 'ServerLangLabel' => 'Язык сервера по умолчанию:', - 'DistanceUnitsLabel' => 'Единицы расстояния:', - 'DistanceUnitsMiles' => 'Мили', - 'DistanceUnitsKM' => 'Километры', - 'SearchDepthLabel' => 'Плотность встреч для автоматического поиска:', - 'SearchDepthText' => 'Это приблизительное количество встреч, которые необходимо найти при автоматическом выборе радиуса. Больше встреч означает больший радиус.', - 'HistoryDepthLabel' => 'Сколько изменений на собраниях сохранять:', - 'HistoryDepthText' => 'Чем дольше история, тем больше будет база данных.', - 'TitleTextLabel' => 'Название экрана администрирования:', - 'TitleTextDefaultText' => 'Введите краткое название для редактирования страницы входа', - 'BannerTextLabel' => 'Подсказка для логина администратора:', - 'BannerTextDefaultText' => 'Введите короткую подсказку для страницы входа', - 'RegionBiasLabel' => 'Регион смещения:', - 'PasswordLengthLabel' => 'Минимальная длина пароля:', - 'PasswordLengthExtraText' => 'Это также повлияет на пароль администратора сервера, указанный выше.', - 'DefaultClosedStatus' => 'Встречи считаются закрытыми по умолчанию:', - 'DefaultClosedStatusExtraText' => 'Это в первую очередь влияет на экспорт в NAWS.', - 'DurationLabel' => 'Продолжительность встречи по умолчанию:', - 'DurationHourLabel' => 'Часы', - 'DurationMinutesLabel' => 'Минуты', - 'LanguageSelectorEnableLabel' => 'Выбор языка отображения при входе в систему:', - 'LanguageSelectorEnableExtraText' => 'Если вы нажмёте это, на экране входа появится всплывающее меню, чтобы администраторы могли выбрать свой язык.', - 'SemanticAdminLabel' => 'Включить семантическое администрирование:', - 'SemanticAdminExtraText' => 'Если этот флажок не установлен, все администрирование должно выполняться через логин корневого сервера (без приложения) (No Apps)).', - 'EmailContactEnableLabel' => 'Разрешить контакты электронной почты встреч:', - 'EmailContactEnableExtraText' => 'Если вы выберете это, посетители сайта смогут отправлять электронные письма с записями собраний.', - 'EmailContactAdminEnableLabel' => 'Включить администратора службы поддержки на эти электронные письма:', - 'EmailContactAdminEnableExtraText' => 'Отправляет копии этих писем администратору сервисного органа (если они не являются основным получателем)).', - 'EmailContactAllAdminEnableLabel' => 'Включить всех администраторов сервисных органов в эти электронные письма:', - 'EmailContactAllAdminEnableExtraText' => 'Отправляет копии этих писем всем соответствующим администраторам сервисных органов.', - - 'Page_4_Initialize_Root_Server_Heading' => 'Инициализировать root сервер', - 'Page_4_Initialize_Root_Server_Text' => 'Кнопка ниже инициализирует root server с пустой базой данных и администратора сервера.', - 'Page_4_Initialize_Root_Server_Button' => 'Инициализация root server', - - 'Page_4_Tab' => 'ШАГ 4: Сохранить настройки', - 'Page_4_Heading' => 'Создать файл настроек', - 'Page_4_Text' => 'Root Server не смог создать файл настроек для вас. Вместо этого мы просим вас создать его самостоятельно через FTP или файловый менеджер панели управления, назовите его «auto-config.inc.php» и вставьте в файл следующий текст:', - - 'NAWS_Export_Spreadsheet_Optional' => 'NAWS Экспорт электронных таблиц (необязательно): ', - 'NAWS_Export_Spreadsheet_Initially_Publish' => 'Initialize imported meetings to \'published\': ', - - 'DefaultPasswordLength' => 10, - 'DefaultMeetingCount' => 10, - 'DefaultChangeDepth' => 5, - 'DefaultDistanceUnits' => 'mi', - 'DefaultDurationTime' => '01:30:00', - 'DurationTextInitialText' => 'N.A. Собрания, как правило, продолжительностью 90 минут (полтора часа), если не указано иное.', - 'time_format' => 'g:i A', - 'change_date_format' => 'g:i A, n/j/Y', - 'BannerTextInitialText' => 'Логин Администратора :', - 'TitleTextInitialText' => 'Basic Meeting List Toolbox Администрирование ', - 'DefaultRegionBias' => 'мы', - 'search_spec_map_center' => array ( 'долгота' => -118.563659, 'широта' => 34.235918, 'приближенность' => 6 ), - 'DistanceChoices' => array ( 2, 5, 10, 20, 50 ), - 'HistoryChoices' => array ( 1, 2, 3, 5, 8, 10, 15 ), - 'PW_LengthChices' => array ( 6, 8, 10, 12, 16 ), - 'ServerAdminDefaultLogin' => 'serveradmin', - - 'Explanatory_Text_1_Initial_Intro' => 'Этот мастер установки проведет вас через процесс создания исходной базы данных, а также файла конфигурации. На последнем шаге мы создадим файл настроек и инициализируем пустую базу данных.', - 'Explanatory_Text_1_DB_Intro' => 'Первое, что вам нужно сделать, это создать новую, пустую базу данных и пользователя базы данных, который имеет полный доступ к этой базе данных. Обычно это делается через панель управления вашего веб-сайта. После того, как вы создали базу данных, вам необходимо ввести информацию об этой базе данных в текстовые элементы на этой странице..', - - 'Explanatory_Text_2_Region_Bias_Intro' => '«Регион смещения» - это код, который отправляется в Google по завершении поиска местоположения и может помочь Google разобраться в неоднозначных поисковых запросах.', - 'Explanatory_Text_2_API_key_Intro' => '«Ключ API» - это ключ, который you need to register with Google чтобы иметь возможность использовать их картографический сервис.', - 'Explanatory_Text_2_API_key_2_Intro' => 'Вам потребуется предоставить действительный ключ API для создания новых собраний на корневом сервере.', - - 'Explanatory_Text_3_Server_Admin_Intro' => 'Администратор сервера является основным пользователем сервера. Это единственная учетная запись, которая может создавать новых пользователей и службы и является очень мощной. Вы должны создать идентификатор входа в систему и нетривиальный пароль для этой учетной записи. Вы сможете изменить другие аспекты учетной записи на главном сервере после настройки базы данных.', - 'Explanatory_Text_3_Misc_Intro' => 'Это различные настройки, которые влияют на поведение и внешний вид корневого сервера.', - - 'Explanatory_Text_4_Main_Intro' => 'Если вы ввели информацию базы данных, предоставили действительный ключ API Карт Google и указали регистрационную информацию для Администратора сервера, тогда вы можете инициализировать корневой сервер здесь. Помните, что база данных должна быть ПОЛНОСТЬЮ ПУСТО из таблиц корневого сервера BMLT для этого сервера (в ней могут быть таблицы для других серверов или служб).', - 'Explanatory_Text_4_NAWS_Export' => 'Optionally, you can import the meetings from a NAWS export spreadsheet. Uncheck the box to initialize them to \'unpublished\'. (This is useful if many of the new meetings will need to be edited or deleted, and you don\'t want them showing up in the meantime.)', - 'Explanatory_Text_4_File_Intro' => 'Текст в поле ниже - это исходный код PHP для основного файла настроек. Вам нужно будет создать файл на сервере с этим текстом. Файл находится на том же уровне, что и каталог основного сервера для корневого сервера.', - 'Explanatory_Text_4_File_Extra' => 'Вы также должны убедиться, что права доступа к файлам ограничены (chmod 0644). Это предотвращает запись файла, и корневой сервер не будет работать, если файл не имеет правильных разрешений.', - 'Page_4_PathInfo' => 'Файл должен быть размещен как %s/auto-config.inc.php, где ваш %s каталог. После того, как файл был создан и вы поместили в него вышеуказанный текст, вы должны выполнить следующую команду, чтобы убедиться, что права доступа правильные:', - 'Page_4_Final' => 'Как только все это будет завершено, обновите эту страницу, и вы должны увидеть страницу входа на корневой сервер.', - 'FormatLangNamesLabel' => 'Введите дополнительные языки в формате code1:name1 (Например "fa:farsi ru:russian"):', -); diff --git a/src/legacy/local_server/server_admin/lang/ru/name.txt b/src/legacy/local_server/server_admin/lang/ru/name.txt deleted file mode 100644 index db514675c..000000000 --- a/src/legacy/local_server/server_admin/lang/ru/name.txt +++ /dev/null @@ -1 +0,0 @@ -Русский \ No newline at end of file diff --git a/src/legacy/local_server/server_admin/lang/ru/server_admin_strings.inc.php b/src/legacy/local_server/server_admin/lang/ru/server_admin_strings.inc.php deleted file mode 100644 index c0fbbbcb5..000000000 --- a/src/legacy/local_server/server_admin/lang/ru/server_admin_strings.inc.php +++ /dev/null @@ -1,493 +0,0 @@ -. */ - -defined('BMLT_EXEC') or die('Cannot Execute Directly'); // Makes sure that this file is in the correct context. - -$comdef_server_admin_strings = array('server_admin_disclosure' => 'Администрирование сервера', - 'server_admin_naws_spreadsheet_label' => 'Обновленный список World ID:', // TODO: was changed to "Updated World Committee Codes Spreadsheet" - 'update_world_ids_button_text' => 'Обновление World ID собраний', // TODO: was changed to "'Update World Committee Codes" - 'update_world_ids_from_spreadsheet_dropdown_text' => 'Обновление World ID из таблицы NAWS', // TODO: was changed to "Update World Committee Codes (Group IDs from NAWS) from NAWS Spreadsheet" - 'server_admin_error_no_world_ids_updated' => 'Не найдено обновлений World ID . Это может быть связано с тем, что у вашего пользователя нет прав на обновление отправленных собраний.', - 'server_admin_error_required_spreadsheet_column' => 'Обязательный столбец не существует в электронной таблице: ', - 'server_admin_error_bmlt_id_not_integer' => 'Предоставленный bmlt_id не является целым числом: ', - 'server_admin_error_could_not_create_reader' => 'Не удалось создать reader для файла: ', - 'server_admin_error_no_files_uploaded' => 'Файлы не были загружены.', - 'server_admin_error_service_bodies_already_exist' => 'Сервисные органы со следующими World ID уже существуют: ', - 'server_admin_error_meetings_already_exist' => 'Собрания со следующими World ID уже существуют: ', - 'server_admin_ui_num_meetings_updated' => 'Количество обновленных собраний: ', - 'server_admin_ui_num_meetings_not_updated' => 'Номера собраний, которые не нуждались в обновлении: ', - 'server_admin_ui_warning' => 'ПРЕДУПРЕЖДЕНИЕ', - 'server_admin_ui_errors' => 'Ошибка(и)', - 'server_admin_ui_deleted_meetings_marked' => 'Number of deleted meetings marked so that they won\'t appear in future NAWS exports: ', - // TODO: re-translate this string (English version has been updated) - // 'server_admin_ui_problem_meetings' => 'Собрания были найдены в таблице, которой не было в базе данных. Это могло произойти, если собрание удалено или не опубликовано. Не достающие ID собраний : ', - 'server_admin_ui_problem_meetings' => 'meetings were found in the spreadsheet that couldn\'t be updated. Problem meeting IDs: ', - 'server_admin_ui_service_bodies_created' => 'Созданы сервисные органы: ', - 'server_admin_ui_meetings_created' => 'Собрания созданы: ', - 'server_admin_ui_users_created' => 'Пользователи создали: ', - 'server_admin_ui_refresh_ui_text' => 'Выйдите, а затем войдите снова, чтобы увидеть новые сервисные органы, пользователей и собрания.', - 'import_service_bodies_and_meetings_button_text' => 'Импорт собраний и органов обслуживания', - 'import_service_bodies_and_meetings_dropdown_text' => 'Импорт органов обслуживания и собраний из экспорта NAWS', - 'server_admin_naws_import_spreadsheet_label' => 'NAWS импортированные таблицы :', - 'server_admin_naws_import_initially_publish' => 'Initialize imported meetings to \'published\': ', - 'server_admin_naws_import_explanation' => 'Uncheck the box to initialize imported meetings to \'unpublished\'. (This is useful if many of the new meetings will need to be edited or deleted, and you don\'t want them showing up in the meantime.)', - 'account_disclosure' => 'Мой аккаунт', - 'account_name_label' => 'Имя аккаунта:', - 'account_login_label' => 'Мой логин:', - 'account_type_label' => 'Меня зовут:', - 'account_type_1' => 'Администратор сервера', - 'account_type_2' => 'Администратор орагана обслуживания', - 'ServerMapsURL' => 'https://maps.googleapis.com/maps/api/geocode/xml?address=##SEARCH_STRING##&sensor=false', - 'account_type_4' => 'Жалкий Неудачник который даже не должен был иметь доступ к этой странице - Автор этого программного обеспечения - упырь!', - 'account_type_5' => 'Наблюдатель органа обслуживания:', - 'change_password_label' => 'Изменить мой пароль на:', - 'change_password_default_text' => 'Оставь это в покое, если не хочешь менять свой пароль', - 'account_email_label' => 'Мой электронный адрес:', - 'email_address_default_text' => 'Введите адрес электронной почты', - 'account_description_label' => 'Мое описание:', - 'account_description_default_text' => 'Введите описание', - 'account_change_button_text' => 'Изменить настройки моей учетной записи', - 'account_change_fader_success_text' => 'Информация об учетной записи была успешно изменена', - 'account_change_fader_failure_text' => 'Информация об учетной записи не была изменена', - 'meeting_editor_disclosure' => 'Редактор собраний', - 'meeting_editor_already_editing_confirm' => 'Вы в настоящее время редактируете другое собрание. Вы хотите потерять все изменения в этом собрании?', - 'meeting_change_fader_success_text' => 'Собрание успешно изменено', - 'meeting_change_fader_failure_text' => 'Собрание не было изменено', - 'meeting_change_fader_success_delete_text' => 'Собрание успешно удалено', - 'meeting_change_fader_fail_delete_text' => 'Собрание не было удалено', - 'meeting_change_fader_success_add_text' => 'Новое собрание успешно добавлено', - 'meeting_change_fader_fail_add_text' => 'Новое собрание не было добавлено', - 'meeting_text_input_label' => 'Поиск текста:', - 'access_service_body_label' => 'У меня есть доступ к:', - 'meeting_text_input_default_text' => 'Введите текст для поиска', - 'meeting_text_location_label' => 'Это местоположение или почтовый индекс', - 'meeting_search_weekdays_label' => 'Поиск выбранных будней:', - 'meeting_search_weekdays_names' => array('ВСЕ', 'Воскресенье', 'Понедельник', 'Вторник', 'Среда', 'Четверг', 'Пятница', 'Суббота'), - 'meeting_search_service_bodies_label' => 'Поиск в выбранных органах обслуживания:', - 'meeting_search_start_time_label' => 'Поиск по времени начала собрания:', - 'meeting_search_start_time_all_label' => 'Любое время', - 'meeting_search_start_time_morn_label' => 'Утро', - 'meeting_search_start_time_aft_label' => 'Днем', - 'meeting_search_start_time_eve_label' => 'Вечер', - 'meeting_search_no_results_text' => 'Собрания не найдены', - 'meeting_editor_tab_specifier_text' => 'Поиск собраний', - 'meeting_editor_tab_editor_text' => 'Редактировать собрания', // TODO: change to 'Edit Or Create Meetings' - 'meeting_editor_create_new_text' => 'Создать новое собрание', - 'meeting_editor_location_map_link' => 'Карта местности', - 'meeting_editor_screen_match_ll_button' => 'Установите долготу и широту в адрес', - 'meeting_editor_screen_default_text_prompt' => 'Введите текст или число', - 'meeting_is_published' => 'Собрание опубликовано', - 'meeting_unpublished_note' => 'Примечание. Отмена публикации собрания означает временное закрытие. Если эта встреча закрыта навсегда, пожалуйста, удалите ее.', - 'meeting_editor_screen_meeting_name_label' => 'Название Собрания:', - 'meeting_editor_screen_meeting_name_prompt' => 'Введите название собрания', - 'meeting_editor_screen_meeting_weekday_label' => 'Будни:', - 'meeting_editor_screen_meeting_start_label' => 'Начало времени собрания:', - 'meeting_editor_screen_meeting_time_zone_label' => 'Meeting Time Zone:', - 'meeting_editor_screen_meeting_am_label' => '00:00 - 12:00', - 'meeting_editor_screen_meeting_pm_label' => '12:00 - 00:00', - 'meeting_editor_screen_meeting_noon_label' => 'Полдень', - 'meeting_editor_screen_meeting_midnight_label' => 'полночь', - 'meeting_editor_screen_meeting_duration_label' => 'Продолжительность:', - 'meeting_editor_screen_meeting_oe_label' => 'Открыто-закрыто', - 'meeting_editor_screen_meeting_cc_label' => 'Код мирового комитета:', - 'meeting_editor_screen_meeting_cc_advice' => 'Normally leave this field alone (see documentation).', // TODO: translate - 'meeting_editor_screen_meeting_contact_label' => 'Контактный E-mail собрания', - 'meeting_editor_screen_meeting_contact_prompt' => 'Введите адрес электронной почты для контакта только для этого собрания', - 'meeting_editor_screen_meeting_sb_label' => 'Орган обслуживания:', - 'meeting_editor_screen_meeting_sb_default_value' => 'Нет выбранного органа обслуживания', - 'meeting_editor_screen_meeting_longitude_label' => 'Долгота:', - 'meeting_editor_screen_meeting_longitude_prompt' => 'Введите долготу', - 'meeting_editor_screen_meeting_latitude_label' => 'Широта', - 'meeting_editor_screen_meeting_latitude_prompt' => 'Введите широту', - 'meeting_editor_screen_meeting_location_label' => 'Расположение:', - 'meeting_editor_screen_meeting_location_prompt' => 'Введите название местоположения (например, название здания)', - 'meeting_editor_screen_meeting_info_label' => 'Дополнительная информация:', - 'meeting_editor_screen_meeting_info_prompt' => 'Введите любую дополнительную информацию о местоположении', - 'meeting_editor_screen_meeting_street_label' => 'Адрес улицы:', - 'meeting_editor_screen_meeting_street_prompt' => 'Введите адрес улицы', - 'meeting_editor_screen_meeting_neighborhood_label' => 'Окрестности:', - 'meeting_editor_screen_meeting_neighborhood_prompt' => 'Войдите в Район (Не Город или Подраздел Города)', - 'meeting_editor_screen_meeting_borough_label' => 'Район / Город Подраздел:', - 'meeting_editor_screen_meeting_borough_prompt' => 'Введите район или городской край (не соседний)', - 'meeting_editor_screen_meeting_city_label' => 'Город:', - 'meeting_editor_screen_meeting_city_prompt' => 'Название города (Не округ или городской округ)', - 'meeting_editor_screen_meeting_county_label' => 'Страна\республика:', - 'meeting_editor_screen_meeting_county_prompt' => 'Введите название страны или республики', - 'meeting_editor_screen_meeting_state_label' => 'Край\область', - 'meeting_editor_screen_meeting_state_prompt' => 'Введите название края или области', - 'meeting_editor_screen_meeting_zip_label' => 'Индекс / Почтовый индекс:', - 'meeting_editor_screen_meeting_zip_prompt' => 'Почтовый индекс', - 'meeting_editor_screen_meeting_nation_label' => 'Нация:', - 'meeting_editor_screen_meeting_nation_prompt' => 'Введите название нации', - 'meeting_editor_screen_meeting_comments_label' => 'Комментарии:', - 'meeting_editor_screen_meeting_train_lines_label' => 'Линии поезда:', - 'meeting_editor_screen_meeting_bus_lines_label' => 'Автобусные линии:', - 'meeting_editor_screen_meeting_phone_meeting_number_label' => 'Телефонный номер для набора номера:', - 'meeting_editor_screen_meeting_phone_meeting_number_prompt' => 'Введите телефонный номер для телефона или виртуального собрания', - 'meeting_editor_screen_meeting_virtual_meeting_link_label' => 'Ссылка на виртуальную встречу:', - 'meeting_editor_screen_meeting_virtual_meeting_link_prompt' => 'Введите ссылку для виртуальной встречи', - 'meeting_editor_screen_meeting_virtual_meeting_additional_info_label' => 'Virtual Meeting Additional Information:', - 'meeting_editor_screen_meeting_virtual_meeting_additional_info_prompt' => 'Enter any additional information for joining the virtual meeting, including directly from the app. For example, if the meeting uses Zoom, "Zoom ID: 456 033 8613, Passcode: 1953" would be appropriate.', - 'meeting_editor_screen_meeting_venue_type' => 'Venue Type:', - 'meeting_editor_screen_meeting_venue_type_inperson' => 'In-Person', - 'meeting_editor_screen_meeting_venue_type_virtual' => 'Virtual', - 'meeting_editor_screen_meeting_venue_type_virtualTC' => 'Virtual (temporarily replacing an in-person)', - 'meeting_editor_screen_meeting_venue_type_hybrid' => 'Hybrid (both in-person and virtual)', - 'meeting_editor_screen_meeting_venue_type_validation' => 'You must select a venue type.', - 'meeting_editor_screen_meeting_virtual_info_missing' => 'Virtual or hybrid meetings must have a Virtual Meeting Link, a Phone Meeting Dial-in Number, or Virtual Meeting Additional Information', - 'meeting_editor_screen_meeting_location_warning' => 'Meeting should have a location (at least a city/town and state/province, or a zip/postal code).', - 'meeting_editor_screen_meeting_address_warning' => 'In-person or hybrid meetings should have a street address.', - 'meeting_editor_screen_meeting_url_validation' => 'Virtual Meeting Link is not a valid URL.', - 'meeting_editor_screen_meeting_url_or_phone_warning' => 'Virtual or hybrid meetings should have either a Virtual Meeting Link or a Phone Meeting Dial-in Number', - 'meeting_editor_screen_meeting_additional_warning' => 'Please also fill in Virtual Meeting Additional Information if there is a Virtual Meeting Link.', - 'meeting_editor_screen_in_person_virtual_info_warning' => 'In-person meetings shouldn\'t have any virtual meeting information.', - 'meeting_editor_screen_meeting_virtual_location_info_warning' => 'Virtual meetings shouldn\'t have a location name or address.', - 'meeting_editor_screen_meeting_validation_warning' => 'There are warnings. Are you sure you want to save anyway? If not, press \'cancel\' and go to the Location tab to see the warnings in place and address them.', - 'meeting_editor_screen_meeting_validation_failed' => 'Unable to save due to input errors. Please go to the Location tab to address them, and then retry saving. Errors: ', - 'meeting_editor_screen_meeting_validation_warnings' => 'Input warnings shown on the Location tab: ', - 'meeting_editor_screen_meeting_contact_name_1_label' => 'Имя Контакта 1 :', - 'meeting_editor_screen_meeting_contact_email_1_label' => 'Электронная почта Контакта 1 :', - 'meeting_editor_screen_meeting_contact_phone_1_label' => 'Телефон Контакта 1 :', - 'meeting_editor_screen_meeting_contact_name_2_label' => 'Имя Контакта 2 :', - 'meeting_editor_screen_meeting_contact_email_2_label' => 'Электронная почта Контакта 2:', - 'meeting_editor_screen_meeting_contact_phone_2_label' => 'Телефон Контакта 2:', - 'meeting_editor_screen_meeting_publish_search_prompt' => 'Искать:', - 'meeting_editor_screen_meeting_publish_search_pub' => 'Только опубликованные Собрания', - 'meeting_editor_screen_meeting_publish_search_unpub' => 'Только неопубликованные Собрания', - 'meeting_editor_screen_meeting_visibility_advice' => 'Собрания которые не отображаются в обычном поиске.', - 'meeting_editor_screen_meeting_publish_search_all' => 'Все Собрания', - 'meeting_editor_screen_meeting_create_button' => 'Создать новое Собрание', - 'meeting_editor_screen_delete_button' => 'Удалить это Собрание', - 'meeting_editor_screen_delete_button_confirm' => 'Вы уверены, что хотите удалить это Собрание?', - 'meeting_editor_screen_cancel_button' => 'Отменить', - 'logout' => 'Выход', - 'meeting_editor_screen_cancel_confirm' => 'Вы уверены, что хотите отменить редактирование этого Собрания и потерять все изменения??', - 'meeting_lookup_failed' => 'Не удалось найти адрес.', - 'meeting_lookup_failed_not_enough_address_info' => 'Недостаточно информации действительного адреса для поиска.', - 'meeting_create_button_name' => 'Сохранить это как новое Собрание', - 'meeting_saved_as_a_copy' => 'Сохранить это Собрание как копию (Создает новое собрание)', - 'meeting_save_buttonName' => 'Сохранить изменения для этого Собрания', - 'meeting_editor_tab_bar_basic_tab_text' => 'Основной', - 'meeting_editor_tab_bar_location_tab_text' => 'Локация', - 'meeting_editor_tab_bar_format_tab_text' => 'Формат', - 'meeting_editor_tab_bar_other_tab_text' => 'Другое', - 'meeting_editor_tab_bar_history_tab_text' => 'История', - 'meeting_editor_result_count_format' => '%% Собраний найдено', - 'meeting_id_label' => 'ID Собрания:', - 'meeting_editor_default_zoom' => '13', - 'meeting_editor_default_weekday' => '2', - 'meeting_editor_default_start_time' => '20:30:00', - 'login_banner' => 'Панель инструментов основного списка Собраний', - 'login_underbanner' => 'Консоль администрирования корневого сервера', - 'login' => 'Login ID', - 'password' => 'Пароль', - 'button' => 'Логин', - 'cookie' => 'Вы должны включить куки для администрирования этого сервера.', - 'noscript' => 'Вы не можете администрировать этот сайт без JavaScript.', - 'title' => 'Пожалуйста, войдите, чтобы администрировать сервер.', - 'edit_Meeting_object_not_found' => 'ОШИБКА: Собрание не найдено.', - 'edit_Meeting_object_not_changed' => 'ОШИБКА: Собрание не изменилось.', - 'edit_Meeting_auth_failure' => 'Вы не авторизованы для редактирования этого Собрания.', - 'not_auth_1' => 'НЕ РАЗРЕШЕНО', - 'not_auth_2' => 'Вы не авторизованы для администрирования этого сервера.', - 'not_auth_3' => 'Возникла проблема с именем пользователя или паролем, которые вы ввели.', - 'email_format_bad' => 'Введенный вами адрес электронной почты был отформатирован неправильно.', - 'history_header_format' => '
%sby %s
', - 'history_no_history_available_text' => '

Нет истории для этой встречи

', - 'service_body_editor_disclosure' => 'Администрация органа обслуживания', - 'service_body_change_fader_success_text' => 'Орган ослуживания был успешно изменен', - 'service_body_change_fader_fail_text' => 'Не удалось изменить орган обслуживания', - 'service_body_editor_screen_sb_id_label' => 'ID:', - 'service_body_editor_screen_sb_name_label' => 'Имя:', - 'service_body_name_default_prompt_text' => 'Введите название этого органа обслуживания', - 'service_body_parent_popup_label' => 'Локальный комитет обслуживания:', - 'service_body_parent_popup_no_parent_option' => 'Без родителей (Верхний уровень)', - 'service_body_editor_screen_sb_admin_user_label' => 'Основной администратор:', - 'service_body_editor_screen_sb_admin_description_label' => 'Описание:', - 'service_body_description_default_prompt_text' => 'Введите описание этого органа обслуживания', - 'service_body_editor_screen_sb_admin_email_label' => 'Contact Email:', - 'service_body_email_default_prompt_text' => 'Введите контактный адрес электронной почты для этого органа обслуживания', - 'service_body_editor_screen_sb_admin_uri_label' => 'URL веб сайта:', - 'service_body_uri_default_prompt_text' => 'Введите URL веб-сайта для этого Органа обслуживания', - 'service_body_editor_screen_sb_admin_full_editor_label' => 'Редактирование полного списка собраний:', - 'service_body_editor_screen_sb_admin_full_editor_desc' => 'Эти пользователи могут редактировать любые собрания в этом Органе обслуживания.', - 'service_body_editor_screen_sb_admin_editor_label' => 'Редактор основного списка собраний:', - 'service_body_editor_screen_sb_admin_editor_desc' => 'Эти пользователи могут редактировать любые собрания в этом Органе обслуживания, но только если они не опубликованы.', - 'service_body_editor_screen_sb_admin_observer_label' => 'Наблюдатели:', - 'service_body_editor_screen_sb_admin_observer_desc' => 'Эти пользователи могут видеть скрытую информацию (например, адреса электронной почты), но не могут ничего редактировать.', - 'service_body_dirty_confirm_text' => 'Вы внесли изменения в этот Органа обслуживания. Вы хотите потерять свои изменения?', - 'service_body_save_button' => 'Сохранить эти изменения Органа обслуживания', - 'service_body_create_button' => 'Создать Орган обслуживания', - 'service_body_delete_button' => 'Удалить Орган обслуживания', - 'service_body_delete_perm_checkbox' => 'Удалить этот Орган обслуживания навсегда', - 'service_body_delete_button_confirm' => 'Вы уверены, что хотите удалить этот Орган обслуживания? Перед выполнением этой функции убедитесь, что все собрания удалены или переданы другому органу обслуживания.', - 'service_body_delete_button_confirm_perm' => 'Этот Орган обслуживания будет удален навсегда!', - 'service_body_change_fader_create_success_text' => 'Орган обслуживания был успешно создан', - 'service_body_change_fader_create_fail_text' => 'Не удалось создать Орган обслуживания', - 'service_body_change_fader_delete_success_text' => 'Орган обслуживания успешно удален', - 'service_body_change_fader_delete_fail_text' => 'Не удалось удалить Орган обслуживания', - 'service_body_change_fader_fail_no_data_text' => 'Не удалось изменить Орган обслуживания, Потому что не было предоставлено данных', - 'service_body_change_fader_fail_cant_find_sb_text' => 'Не удалось изменить Орган обслуживания, так как он небыли найден', - 'service_body_change_fader_fail_cant_update_text' => 'Не удалось изменить Орган обслуживания, Поскольку он не был обновлен', - 'service_body_change_fader_fail_bad_hierarchy' => 'Не удалось изменить Орган обслуживания, Поскольку выбранный владелец Органа обслуживания находится под этим сервисным органом, And Cannot Be Used', - 'service_body_cancel_button' => 'Восстановить в оригинал', - 'service_body_editor_type_label' => 'Тип Органа обслуживания:', - 'service_body_editor_type_c_comdef_service_body__GRP__' => 'Группа', - 'service_body_editor_type_c_comdef_service_body__COP__' => 'Co-Op', - 'service_body_editor_type_c_comdef_service_body__ASC__' => 'Комитет по территориальному обслуживанию', - 'service_body_editor_type_c_comdef_service_body__RSC__' => 'Конференция по Региональному обслуживанию', - 'service_body_editor_type_c_comdef_service_body__WSC__' => 'Всемирная Конференция по обслуживанию', - 'service_body_editor_type_c_comdef_service_body__MAS__' => 'Метро Площадь', - 'service_body_editor_type_c_comdef_service_body__ZFM__' => 'Зональный форум', - 'service_body_editor_type_c_comdef_service_body__GSU__' => 'Групповое подразделение обслуживания', - 'service_body_editor_type_c_comdef_service_body__LSU__' => 'Локальная служба', - 'service_body_editor_screen_helpline_label' => 'Телефон доверия:', - 'service_body_editor_screen_helpline_prompt' => 'Введите номер телефона горячей линии', - 'service_body_editor_uri_naws_format_text' => 'Получить собрания для этого органа обслуживания в NAWS-Совместимом файле', - 'edit_Meeting_meeting_id' => 'ID Собрания:', - 'service_body_editor_create_new_sb_option' => 'Создать новый Орган обслуживания', - 'service_body_editor_screen_world_cc_label' => 'Код Мирового Комитета:', - 'service_body_editor_screen_world_cc_prompt' => 'Введите код Мирового комитета', - 'user_editor_disclosure' => 'Администрирование пользователя', - 'user_editor_create_new_user_option' => 'Создать нового пользователя', - 'user_editor_screen_sb_id_label' => 'ID:', - 'user_editor_account_login_label' => 'Логин пользователя:', - 'user_editor_login_default_text' => 'Ввести Логин пользователя', - 'user_editor_account_type_label' => 'Пользователь это:', - 'user_editor_user_owner_label' => 'Принадлежит: ', - 'user_editor_account_type_1' => 'Администраторский сервер', - 'user_editor_account_type_2' => 'Админ Органа обслуживания', - 'user_editor_account_type_3' => 'Редактор Органа обслуживания', - 'user_editor_account_type_5' => 'Наблюдатель органа обслуживания', - 'user_editor_account_type_4' => 'Инвалидный пользователь', - 'user_editor_account_name_label' => 'Имя пользователя:', - 'user_editor_name_default_text' => 'Введите имя пользователя', - 'user_editor_account_description_label' => 'Описание:', - 'user_editor_description_default_text' => 'Введите описание пользователя', - 'user_editor_account_email_label' => 'Email:', - 'user_editor_email_default_text' => 'Введите Email пользователя', - 'user_change_fader_success_text' => 'Пользователь был успешно изменен', - 'user_change_fader_fail_text' => 'Не удалось изменить пользователя', - 'user_change_fader_create_success_text' => 'Пользователь был успешно создан', - 'user_change_fader_create_fail_text' => 'Не удалось создать пользователя', - 'user_change_fader_create_fail_already_exists' => 'Логин для пользователя, которого вы пытаетесь создать, уже существует.', - 'user_change_fader_delete_success_text' => 'Пользователь был успешно удален', - 'user_change_fader_delete_fail_text' => 'Ошибка удаления пользователя', - 'user_save_button' => 'Сохранить изменения для этого пользователя', - 'user_create_button' => 'Создать нового пользователя', - 'user_cancel_button' => 'Восстановить оригинал', - 'user_delete_button' => 'Удалить пользователя', - 'user_delete_perm_checkbox' => 'Удалить этого пользователя навсегда', - 'user_password_label' => 'Изменить пароль:', - 'user_new_password_label' => 'Установить пароль:', - 'user_password_default_text' => 'Оставьте это, если вы не хотите сменить пароль', - 'user_new_password_default_text' => 'Вы должны ввести пароль для нового пользователя', - 'user_dirty_confirm_text' => 'Вы внесли изменения в этого пользователя. Хотите потерять свои изменения?', - 'user_delete_button_confirm' => 'Вы уверены, что хотите удалить этого пользователя?', - 'user_delete_button_confirm_perm' => 'Этот пользователь будет удален навсегда!', - 'user_create_password_alert_text' => 'Новые пользователи должны иметь пароль. Вы не указали пароль для этого пользователя.', - 'user_change_fader_fail_no_data_text' => 'Не удалось изменить пользователя, поскольку данные не были предоставлены', - 'user_change_fader_fail_cant_find_sb_text' => 'Не удалось изменить пользователя, поскольку пользователь не найден', - 'user_change_fader_fail_cant_update_text' => 'Не удалось изменить пользователя, поскольку пользователь не был обновлен', - 'format_editor_disclosure' => 'Формат администрирования', - 'format_change_fader_change_success_text' => 'Формат был успешно изменен', - 'format_change_fader_change_fail_text' => 'Ошибка изменения формата', - 'format_change_fader_create_success_text' => 'Формат был успешно создан', - 'format_change_fader_create_fail_text' => 'Формат Создать не удалось', - 'format_change_fader_delete_success_text' => 'Формат был успешно удален', - 'format_change_fader_delete_fail_text' => 'Ошибка удаления формата', - 'format_change_fader_fail_no_data_text' => 'Не удалось изменить формат, поскольку не было предоставлено данных', - 'format_change_fader_fail_cant_find_sb_text' => 'Ошибка изменения формата, поскольку формат не найден', - 'format_change_fader_fail_cant_update_text' => 'Ошибка изменения формата, поскольку формат не был обновлен', - 'format_editor_name_default_text' => 'Введите очень краткое описание', - 'format_editor_description_default_text' => 'Введите более подробное описание', - 'format_editor_create_format_button_text' => 'Создать новый формат', - 'format_editor_cancel_create_format_button_text' => 'Отменить', - 'format_editor_create_this_format_button_text' => 'Создать формат', - 'format_editor_change_format_button_text' => 'Изменить формат', - 'format_editor_delete_format_button_text' => 'Удалить формат', - 'format_editor_reset_format_button_text' => 'Восстановить оригинал', - 'need_refresh_message_fader_text' => 'Вы должны обновить эту страницу перед использованием этого раздела', - 'need_refresh_message_alert_text' => 'Поскольку вы внесли изменения в Администрирование сервера, Администрирование тела службы, Администрирование пользователей или Администрирование формата, информация, отображаемая в этом разделе, может быть более неточной, поэтому необходимо обновить страницу. Самый простой способ сделать это - выйти, а затем снова войти.', - 'format_editor_delete_button_confirm' => 'Вы уверены, что хотите удалить этот формат?', - 'format_editor_delete_button_confirm_perm' => 'Этот формат будет удален навсегда!', - 'format_editor_missing_key' => 'This format should have an entry for every language (at least a key).', // TODO: translate - 'format_editor_reserved_key' => 'This key is reserved for a venue type format - please use something different.', // TODO: translate - 'min_password_length_string' => 'Пароль слишком короткий! Длина должна быть не менее % d символов!', - 'AJAX_Auth_Failure' => 'Авторизация не удалась для этой операции. Может быть проблема с конфигурацией сервера.', - 'Maps_API_Key_Warning' => 'Возникла проблема с ключом API Google Maps.', - 'Maps_API_Key_Not_Set' => 'Ключ API Google Maps не установлен.', - 'Observer_Link_Text' => 'Meeting Browser', - 'Data_Transfer_Link_Text' => 'Импорт данных собрания (ПРЕДУПРЕЖДЕНИЕ: заменяет текущие данные!)', - 'MapsURL' => 'https://maps.google.com/maps?q=##LAT##,##LONG##+(##NAME##)&ll=##LAT##,##LONG##', - 'hidden_value' => 'Невозможно отобразить данные - Несанкционированно', - 'Value_Prompts' => array( - 'id_bigint' => 'ID собрания', - 'worldid_mixed' => 'World Services ID', - 'service_body' => 'Орган обслуживания', - 'service_bodies' => 'Органы обслуживания', - 'weekdays' => 'Будние дни', - 'weekday' => 'Собрание собирается каждый', - 'start_time' => 'Собрание начинается в', - 'duration_time' => 'Встреча длится', - 'location' => 'Местоположение', - 'duration_time_hour' => 'Час', - 'duration_time_hours' => 'Часы', - 'duration_time_minute' => 'Минута', - 'duration_time_minutes' => 'Минуты', - 'lang_enum' => 'Язык', - 'formats' => 'Форматы', - 'distance' => 'Расстояние от центра', - 'generic' => 'Собрание НА', - 'close_title' => 'Закрыть это окно сведений о собрании', - 'close_text' => 'Закрыть окно', - 'map_alt' => 'Собрание на карте', - 'map' => 'Посмотреть карту', - 'title_checkbox_unpub_meeting' => 'Эта встреча не опубликована. Это не видно при регулярных поисках.', - 'title_checkbox_copy_meeting' => 'Эта встреча является дубликатом другой встречи. Это также не опубликовано. Её не видно при регулярных поисках.' - ), - 'world_format_codes_prompt' => 'NAWS формат:', - 'world_format_codes' => array( - '' => 'Нет', - 'OPEN' => 'Открыть', - 'CLOSED' => 'Закрыть', - 'WCHR' => 'Доступно для инвалидов', - 'BEG' => 'Новичок', - 'BT' => 'Основной текст', - 'CAN' => 'искусственное освещение', - 'CPT' => '12 Концепций', - 'CW' => 'Добро пожаловать детям', - 'DISC' => 'Обсуждение/Участие', - 'GL' => 'Гей / Лесбиянка', - 'IP' => 'IP Обучение', - 'IW' => 'Это работает как и почему', - 'JFT' => 'Только сегодня', - 'LC' => 'Жить чистым', - 'LIT' => 'Изучение литературы', - 'M' => 'Мужчины', - 'MED' => 'Медитация', - 'NS' => 'Не курить', - 'QA' => 'Вопросы и ответы', - 'RA' => 'Ограниченный доступ', - 'S-D' => 'Speaker/Discussion', // TODO translate - 'SMOK' => 'Курение', - 'SPK' => 'Спикер', - 'STEP' => 'Шаг', - 'SWG' => 'Изучение работы по шагам', - 'TOP' => 'Тема', - 'TRAD' => 'Традиции', - 'VAR' => 'Формат Варьируется', - 'W' => 'Женщины', - 'Y' => 'Молодые люди', - 'LANG' => 'Альтернативные языки', - 'GP' => 'Руководящие принципы', - 'NC' => 'Без детей', - 'CH' => 'Закрытые праздники', - 'VM' => 'Virtual', // TODO translate - 'HYBR' => 'Virtual and In-Person', // TODO translate - 'TC' => 'Temporarily Closed Facility', // TODO translate - 'SPAD' => 'Spiritual Principle a Day', // TODO translate - ), - 'format_type_prompt' => 'Тип формата:', - 'format_type_codes' => array( - '' => 'нет', - 'FC1' => 'Формат собрания (Спикерская, Изучение БТ, И так далее.)', - 'FC2' => 'Код местоположения (Доступно для инвалидов, Ограниченная парковка, и т.д.)', - 'FC3' => 'Общие потребности и ограничения (Мужское собрание, ЛГБТ, Без детей и т. Д.)', - 'O' => 'Посещаемость независимыми (Открыто, Закрыто)', - 'LANG' => 'Язык', - 'ALERT' => 'Формат должен быть особенно заметным (чистота и т. Д.)', - ), - - 'cookie_monster' => 'Этот сайт использует куки для хранения вашего предпочтительного языка.', - 'main_prompts' => array( - 'id_bigint' => 'ID', - 'worldid_mixed' => 'World ID', - 'shared_group_id_bigint' => 'неиспользуемый', - 'service_body_bigint' => 'Service Body ID', - 'weekday_tinyint' => 'Weekday', - 'venue_type' => 'Venue Type', - 'start_time' => 'Время начала', - 'duration_time' => 'Продолжительность', - 'time_zone' => 'Time Zone', - 'formats' => 'Форматы', - 'lang_enum' => 'Язык', - 'longitude' => 'Долгота', - 'latitude' => 'Широта', - 'published' => 'Опубликовано', - 'email_contact' => 'e-mail контакт', - ), - 'check_all' => 'проверить все', - 'uncheck_all' => 'Снять все', - 'automatically_calculated_on_save' => 'Автоматически рассчитывается при сохранении.' -); - -$email_contact_strings = array( - 'meeting_contact_form_subject_format' => "[Список контактов собраний] %", - 'meeting_contact_message_format' => "%s\n--\nЭто сообщение касается встречи, названной \"%s\", которые встречаются в %s, on %s.\nСсылка браузера: %s\nEdit Link: %s\nIt было отправлено непосредственно с веб-сервера списка собраний, а отправитель не знает ваш адрес электронной почты.\nПожалуйста, имейте в виду, что ответ откроет ваш адрес электронной почты.\nЕсли вы используете \"Ответить всем\", и есть несколько получателей электронной почты, вы можете выставлять адреса электронной почты других людей.\nПожалуйста, уважайте конфиденциальность и анонимность людей; включая оригинального отправителя этого сообщения." -); - -$change_type_strings = array( - '__THE_MEETING_WAS_CHANGED__' => 'Собрание изменено.', - '__THE_MEETING_WAS_CREATED__' => 'Собрание создано.', - '__THE_MEETING_WAS_DELETED__' => 'Собрание удалено.', - '__THE_MEETING_WAS_ROLLED_BACK__' => 'Собрание откатилось до прошлой версии.', - - '__THE_FORMAT_WAS_CHANGED__' => 'Формат был изменен.', - '__THE_FORMAT_WAS_CREATED__' => 'Формат был создан.', - '__THE_FORMAT_WAS_DELETED__' => 'Формат был удален.', - '__THE_FORMAT_WAS_ROLLED_BACK__' => 'Формат откатился до прошлой версии.', - - '__THE_SERVICE_BODY_WAS_CHANGED__' => 'Сервисное обслуживание изменено.', - '__THE_SERVICE_BODY_WAS_CREATED__' => 'Сервисное обслуживание создано.', - '__THE_SERVICE_BODY_WAS_DELETED__' => 'Сервисное обслуживание удалено.', - '__THE_SERVICE_BODY_WAS_ROLLED_BACK__' => 'Сервисное обслуживание откатилось до прошлой версии.', - - '__THE_USER_WAS_CHANGED__' => 'Пользователь изменен.', - '__THE_USER_WAS_CREATED__' => 'Пользователь создан.', - '__THE_USER_WAS_DELETED__' => 'Пользователь удален.', - '__THE_USER_WAS_ROLLED_BACK__' => 'Пользователь откатился до предыдущей версии.', - - '__BY__' => 'от', - '__FOR__' => 'для' -); - -$detailed_change_strings = array( - 'was_changed_from' => 'был изменен с', - 'to' => 'to', - 'was_changed' => 'был изменен', - 'was_added_as' => 'был добавлен как', - 'was_deleted' => 'был удален', - 'was_published' => 'Собрание было опубликовано', - 'was_unpublished' => 'Собрание было неопубликовано', - 'formats_prompt' => 'Формат собрания', - 'duration_time' => 'Продолжительность встречи', - 'start_time' => 'Время начала встречи', - 'longitude' => 'Долгота собрания', - 'latitude' => 'Широта собрания', - 'sb_prompt' => 'Собрания изменено следующим органом обслуживания', - 'id_bigint' => 'ID собрания', - 'lang_enum' => 'Язык собрания', - 'worldid_mixed' => 'Общий Group ID', // TODO: translate The World Committee Code - 'weekday_tinyint' => 'День недели, в которую собирается собрание', - 'non_existent_service_body' => 'Сервисный орган больше не существует', -); - -defined('_END_CHANGE_REPORT') or define('_END_CHANGE_REPORT', '.'); diff --git a/src/legacy/local_server/server_admin/lang/sv/data_transfer_strings.php b/src/legacy/local_server/server_admin/lang/sv/data_transfer_strings.php deleted file mode 100755 index 6fa2303ec..000000000 --- a/src/legacy/local_server/server_admin/lang/sv/data_transfer_strings.php +++ /dev/null @@ -1,22 +0,0 @@ -.*/ - defined('BMLT_EXEC') or die('Cannot Execute Directly'); // Makes sure that this file is in the correct context. - - $comdef_data_transfer_strings = array (); diff --git a/src/legacy/local_server/server_admin/lang/sv/install_wizard_strings.php b/src/legacy/local_server/server_admin/lang/sv/install_wizard_strings.php deleted file mode 100755 index 4c0bf128f..000000000 --- a/src/legacy/local_server/server_admin/lang/sv/install_wizard_strings.php +++ /dev/null @@ -1,138 +0,0 @@ -.*/ - defined('BMLT_EXEC') or die('Cannot Execute Directly'); // Makes sure that this file is in the correct context. - - global $comdef_install_wizard_strings; - - $comdef_install_wizard_strings = array ( - 'Database_Version_Error' => 'ERROR: You must have PHP Version 5.6 or greater installed on this server!', - 'Database_PDO_Error' => 'ERROR: You do not have PHP PDO installed!', - 'Database_Type_Error' => 'ERROR: Even though you have PDO, you have no database drivers installed!', - 'Database_TestButton_Text' => 'TEST', - 'Database_TestButton_Success' => 'The database connection was successful.', - 'Database_TestButton_Fail' => 'The database connection failed: ', - 'Database_TestButton_Fail2' => 'The database connection failed because there is already an initialized database.', - 'Database_Whitespace_Note' => 'Warning: %s has whitespace at the beginning or end.', - - 'AJAX_Handler_DB_Connect_Error' => 'The database connection failed! Please make sure that the database exists, IS COMPLETELY EMPTY, the user is created, and that user has full permissions on the empty database.', - 'AJAX_Handler_DB_Established_Error' => 'The database already exists, and has been set up! You cannot use this setup to overwrite an existing database!', - 'AJAX_Handler_DB_Incomplete_Error' => 'There is not enough information to initialize the database!', - - 'NoDatabase_Note_AlreadySet' => 'The database has already been initialized with the provided table prefix. Please choose a new one.', - 'NoDatabase_Note_PasswordIssue' => 'You must choose a username and password for the Server Administrator user.', - 'NoServerAdmin_Note_AlreadySet' => 'There is already an existing database, so you cannot set up a Server Administrator account (One already exists).', - 'NeedLongerPasswordNote' => 'This password is too short. It must be at least %d characters long.', - - 'Prev_Button' => 'PREVIOUS', - 'Next_Button' => 'NEXT', - - 'Page_1_Tab' => 'STEP 1: Database', - 'Page_1_Heading' => 'Database Connection Settings', - 'Page_1_Text' => 'Before you can apply the settings on this page, you must set up a new COMPLETELY EMPTY database, and create a database user that has full user rights on that database.', - - 'Database_Name' => 'Database Name:', - 'Database_Name_Default_Text' => 'Enter A Database Name', - 'Database_Type' => 'Database Type:', - 'Database_Host' => 'Database Host:', - 'Database_Host_Default_Text' => 'Enter A Database Host', - 'Database_Host_Additional_Text' => 'This is usually "localhost."', - 'Table_Prefix' => 'Table Prefix:', - 'Table_Prefix_Default_Text' => 'Enter A Table Prefix', - 'Table_Prefix_Additional_Text' => 'Only for multiple root servers sharing a database.', - 'Database_User' => 'Database User:', - 'Database_User_Default_Text' => 'Enter A Database User Name', - 'Database_PW' => 'Database Password:', - 'Database_PW_Default_Text' => 'Enter A Database Password', - 'Database_PW_Additional_Text' => 'Make this an ugly, difficult password. It has a great deal of power, and you will never need to remember it.', - - 'Maps_API_Key_Warning' => 'There is a problem with the Google Maps API Key.', - - 'Page_2_Tab' => 'STEP 2: Google Maps API', - 'Page_2_Heading' => 'Set The Initial Location For Meetings', - 'Page_2_Text' => 'When saving a meeting, the BMLT Root Server uses the Google Maps API to determine the latitude and longitude for the meeting address. These settings are required to allow the BMLT Root Server to communicate with the Google Maps API.', - - 'Page_3_Tab' => 'STEP 3: Server Settings', - 'Page_3_Heading' => 'Set Various Global Server Settings', - 'Page_3_Text' => 'These are a few settings that affect the administration and general configuration of this server. Most server settings are done in the server itself.', - 'Admin_Login' => 'Server Administrator Login:', - 'Admin_Login_Default_Text' => 'Enter A Server Administrator Login', - 'Admin_Login_Additional_Text' => 'This is the login string for the Server Administrator.', - 'Admin_Password' => 'Server Administrator Password:', - 'Admin_Password_Default_Text' => 'Enter A Server Administrator Password', - 'Admin_Password_Additional_Text' => 'Make sure that this is a non-trivial password! It has a great deal of power! (Also, don\'t forget it).', - 'ServerAdminName' => 'Server Administrator', - 'ServerAdminDesc' => 'Main Server Administrator', - 'ServerLangLabel' => 'Default Server Language:', - 'DistanceUnitsLabel' => 'Distance Units:', - 'DistanceUnitsMiles' => 'Miles', - 'DistanceUnitsKM' => 'Kilometres', - 'SearchDepthLabel' => 'Density of Meetings For Automatic Search:', - 'SearchDepthText' => 'This is an approximation of how many meetings need to be found in the automatic radius selection. More meetings means a bigger radius.', - 'HistoryDepthLabel' => 'How Many Meeting Changes To Save:', - 'HistoryDepthText' => 'The longer the history, the larger the database will become.', - 'TitleTextLabel' => 'The Title Of The Administration Screen:', - 'TitleTextDefaultText' => 'Enter A Short Title For the Editing Login Page', - 'BannerTextLabel' => 'Prompt For Administration Login:', - 'BannerTextDefaultText' => 'Enter A Short Prompt For The Login Page', - 'RegionBiasLabel' => 'Region Bias:', - 'PasswordLengthLabel' => 'Minimum Password Length:', - 'PasswordLengthExtraText' => 'This will also affect the Server Administrator password, above.', - 'DurationLabel' => 'Default Meeting Duration:', - 'DurationHourLabel' => 'Hours', - 'DurationMinutesLabel' => 'Minutes', - 'LanguageSelectorEnableLabel' => 'Display Language Selector On Login:', - 'LanguageSelectorEnableExtraText' => 'If you select this, a popup menu will appear in the login screen, so administrators can select their language.', - 'EmailContactEnableLabel' => 'Allow Email Contacts From Meetings:', - 'EmailContactEnableExtraText' => 'If you select this, site visitors will be able to send emails from meeting records.', - - 'Page_4_Tab' => 'STEP 4: Save The Settings', - 'Page_4_Heading' => 'Create the Settings File', - 'Page_4_Text' => 'The root server was unable to create the settings file for you. Instead, we ask you to create it yourself, via FTP or a control panel file manager, name it "auto-config.inc.php", and paste the following text into the file:', - - 'DefaultPasswordLength' => 10, - 'DefaultMeetingCount' => 10, - 'DefaultChangeDepth' => 5, - 'DefaultDistanceUnits' => 'mi', - 'DefaultDurationTime' => '01:30:00', - 'DurationTextInitialText' => 'N.A. Meetings are usually 90 minutes long (an hour and a half), unless otherwise indicated.', - 'time_format' => 'g:i A', - 'change_date_format' => 'g:i A, n/j/Y', - 'BannerTextInitialText' => 'Administration Login', - 'TitleTextInitialText' => 'Basic Meeting List Toolbox Administration', - 'DefaultRegionBias' => 'us', - 'search_spec_map_center' => array ( 'longitude' => -118.563659, 'latitude' => 34.235918, 'zoom' => 6 ), - 'DistanceChoices' => array ( 2, 5, 10, 20, 50 ), - 'HistoryChoices' => array ( 1, 2, 3, 5, 8, 10, 15 ), - 'PW_LengthChices' => array ( 6, 8, 10, 12, 16 ), - 'ServerAdminDefaultLogin' => 'serveradmin', - - 'Explanatory_Text_1_Initial_Intro' => 'This install wizard will guide you through the process of creating an initial database, as well as a configuration file. In the final step, we will create a settings file, and initialize an empty database.', - 'Explanatory_Text_1_DB_Intro' => 'The first thing that you need to do, is create a new, EMPTY database, and a database user that has full access to that database. This is usually done via your Web site Control Panel. Once you have created the database, you need to enter the information about that database into the text items on this page.', - - 'Explanatory_Text_2_Region_Bias_Intro' => 'The "Region Bias" is a code that is sent to Google when a location search is done, and can help Google to make sense of ambiguous search queries.', - - 'Explanatory_Text_3_Server_Admin_Intro' => 'The Server Administrator is the main user for the server. It is the only account that can create new users and Service bodies, and is very powerful. You should create a login ID and a non-trivial password for this account. You\'ll be able to modify the other aspects of the account on the main server, once the database has been set up.', - 'Explanatory_Text_3_Misc_Intro' => 'These are various settings that affect how the root server behaves and appears.', - - 'Explanatory_Text_4_Main_Intro' => 'If you have entered the database information, provided a valid Google Maps API Key, and specified the login information for the Server Administrator, then you can initialize the root server here. Remember that the database must be COMPLETELY EMPTY of BMLT Root Server tables for this server (It can have tables for other servers or services).', - 'Explanatory_Text_4_NAWS_Export' => 'Optionally, you can import the meetings from a NAWS export spreadsheet. Uncheck the box to initialize them to \'unpublished\'. (This is useful if many of the new meetings will need to be edited or deleted, and you don\'t want them showing up in the meantime.)', - 'Explanatory_Text_4_File_Intro' => 'The text in the box below is the PHP source code for the main settings file. You will need to create a file on the server with this text in it. The file is at the same level as the main server directory for the root server.', - 'Explanatory_Text_4_File_Extra' => 'You also need to make sure that the file permissions are restricted (chmod 0644). This prevents the file from being written, and the root server will not run unless the file has the correct permissions.', - 'Page_4_PathInfo' => 'The file needs to be placed as %s/auto-config.inc.php, which is where your %s directory is. After the file has been created and you have put the above text into it, you should execute the following command to make sure that the permissions are correct:', - 'Page_4_Final' => 'Once all this is complete, refresh this page, and you should see the root server login page.', - 'FormatLangNamesLabel' => 'Enter extra languages in format code1:name1 (example "fa:farsi ru:russian"):', - ); diff --git a/src/legacy/local_server/server_admin/lang/sv/name.txt b/src/legacy/local_server/server_admin/lang/sv/name.txt deleted file mode 100755 index 838494360..000000000 --- a/src/legacy/local_server/server_admin/lang/sv/name.txt +++ /dev/null @@ -1 +0,0 @@ -Svenska \ No newline at end of file diff --git a/src/legacy/local_server/server_admin/lang/sv/server_admin_strings.inc.php b/src/legacy/local_server/server_admin/lang/sv/server_admin_strings.inc.php deleted file mode 100755 index 4e26f243c..000000000 --- a/src/legacy/local_server/server_admin/lang/sv/server_admin_strings.inc.php +++ /dev/null @@ -1,491 +0,0 @@ -. - * Swedish translator webmaster2@nasverige.org Magnus */ - -defined('BMLT_EXEC') or die('Cannot Execute Directly'); // Makes sure that this file is in the correct context. - -$comdef_server_admin_strings = array( - 'server_admin_disclosure' => 'Server Administration', - 'server_admin_naws_spreadsheet_label' => 'Updated World Committee Codes Spreadsheet', - 'update_world_ids_button_text' => 'Update World Committee Codes', - 'update_world_ids_from_spreadsheet_dropdown_text' => 'Update World Committee Codes (Group IDs from NAWS) from NAWS Spreadsheet', - 'server_admin_error_no_world_ids_updated' => 'No World IDs were updated. This could be because your user does not have permission to update the submitted meetings.', - 'server_admin_error_required_spreadsheet_column' => 'Required column does not exist in the spreadsheet: ', - 'server_admin_error_bmlt_id_not_integer' => 'The provided bmlt_id is not an integer: ', - 'server_admin_error_could_not_create_reader' => 'Could not create reader for file: ', - 'server_admin_error_no_files_uploaded' => 'No files were uploaded.', - 'server_admin_error_service_bodies_already_exist' => 'Service bodies with the following World IDs already exist: ', - 'server_admin_error_meetings_already_exist' => 'Meetings with the following World IDs already exist: ', - 'server_admin_ui_num_meetings_updated' => 'Number of meetings updated: ', - 'server_admin_ui_num_meetings_not_updated' => 'Number of meetings that did not need updating: ', - 'server_admin_ui_warning' => 'WARNING', - 'server_admin_ui_errors' => 'Error(s)', - 'server_admin_ui_deleted_meetings_marked' => 'Number of deleted meetings marked so that they won\'t appear in future NAWS exports: ', - 'server_admin_ui_problem_meetings' => 'meetings were found in the spreadsheet that couldn\'t be updated. Problem meeting IDs: ', - 'server_admin_ui_service_bodies_created' => 'Service bodies created: ', - 'server_admin_ui_meetings_created' => 'Meetings created: ', - 'server_admin_ui_users_created' => 'Users created: ', - 'server_admin_ui_refresh_ui_text' => 'Sign out and then sign in again to see the new service bodies, users, and meetings.', - 'import_service_bodies_and_meetings_button_text' => 'Import Service Bodies and Meetings', - 'import_service_bodies_and_meetings_dropdown_text' => 'Import Service Bodies and Meetings from NAWS Export', - 'server_admin_naws_import_spreadsheet_label' => 'NAWS Import Spreadsheet:', - 'server_admin_naws_import_initially_publish' => 'Initialize imported meetings to \'published\': ', - 'server_admin_naws_import_explanation' => 'Uncheck the box to initialize imported meetings to \'unpublished\'. (This is useful if many of the new meetings will need to be edited or deleted, and you don\'t want them showing up in the meantime.)', - 'account_disclosure' => 'Mitt konto', - 'account_name_label' => 'Kontonamn:', - 'account_login_label' => 'Min inloggning:', - 'account_type_label' => 'Jag är en:', - 'account_type_1' => 'Server Administratör', - 'account_type_2' => 'Serviceenhet Administratör', - 'ServerMapsURL' => 'https://maps.googleapis.com/maps/api/geocode/xml?address=##SEARCH_STRING##&sensor=false', - 'account_type_4' => 'hacker? tydligen inte...', - 'account_type_5' => 'Serviceenhet övervakare', - 'change_password_label' => 'Ändra mitt lösenord till:', - 'change_password_default_text' => 'Låt denna vara såvida du inte vill byta lösenord', - 'account_email_label' => 'Min Epostadress:', - 'email_address_default_text' => 'Fyll i en Epostadress', - 'account_description_label' => 'Om mig:', - 'account_description_default_text' => 'Fyll i en "om mig" text', - 'account_change_button_text' => 'Ändra mina kontoinställningar', - 'account_change_fader_success_text' => 'Kontoinställningarna ändrades framgångsrikt.', - 'account_change_fader_failure_text' => 'Kontoinställningarna ändrades inte!', - 'meeting_editor_disclosure' => 'Ändra möten', - 'meeting_editor_already_editing_confirm' => 'Du arbetar med ett annat möte. Vill du fortsätta och tappa ev ändringar?', - 'meeting_change_fader_success_text' => 'Mötet ändrades framgångsrikt', - 'meeting_change_fader_failure_text' => 'Mötet ändrades inte!', - 'meeting_change_fader_success_delete_text' => 'Mötet kasserat', - 'meeting_change_fader_fail_delete_text' => 'Mötet kasserades inte!', - 'meeting_change_fader_success_add_text' => 'Nytt möte registrerat', - 'meeting_change_fader_fail_add_text' => 'Det nya mötet registrerades inte!', - 'meeting_text_input_label' => 'Sök efter text:', - 'access_service_body_label' => 'Jag har tillgång till:', - 'meeting_text_input_default_text' => 'Fyll i någon söktext', - 'meeting_text_location_label' => 'Sök efter närmaste möte till en plats', - 'meeting_search_weekdays_label' => 'Sök möten utvalda dagar:', - 'meeting_search_weekdays_names' => array('Alla', 'Söndag', 'Måndag', 'Tisdag', 'Onsdag', 'Torsdag', 'Fredag', 'Lördag'), - 'meeting_search_service_bodies_label' => 'Sök i utvalda servicenheter:', - 'meeting_search_start_time_label' => 'Sök efter mötets starttid:', - 'meeting_search_start_time_all_label' => 'Valfri tid', - 'meeting_search_start_time_morn_label' => 'Morgon', - 'meeting_search_start_time_aft_label' => 'Eftermiddag', - 'meeting_search_start_time_eve_label' => 'Kväll', - 'meeting_search_no_results_text' => 'Inga möten funna.', - 'meeting_editor_tab_specifier_text' => 'Sök efter möten', - 'meeting_editor_tab_editor_text' => 'Ändra möten', // TODO: change to 'Edit Or Create Meetings' - 'meeting_editor_create_new_text' => 'Skapa ett nytt möte', - 'meeting_editor_location_map_link' => 'Karta', - 'meeting_editor_screen_match_ll_button' => 'Ange longitude och latitud för adressen', - 'meeting_editor_screen_default_text_prompt' => 'Fyll i text eller nummer', - 'meeting_is_published' => 'Mötet är nu publicerat', - 'meeting_unpublished_note' => 'Note: Unpublishing a meeting indicates a temporary closure. If this meeting has closed permanently, please delete it.', - 'meeting_editor_screen_meeting_name_label' => 'Mötets namn:', - 'meeting_editor_screen_meeting_name_prompt' => 'Fyll i mötets namn', - 'meeting_editor_screen_meeting_weekday_label' => 'Veckodag:', - 'meeting_editor_screen_meeting_start_label' => 'Mötets starttid:', - 'meeting_editor_screen_meeting_time_zone_label' => 'Meeting Time Zone:', - 'meeting_editor_screen_meeting_am_label' => 'AM', - 'meeting_editor_screen_meeting_pm_label' => 'PM', - 'meeting_editor_screen_meeting_noon_label' => 'Middag', - 'meeting_editor_screen_meeting_midnight_label' => 'Midnatt', - 'meeting_editor_screen_meeting_duration_label' => 'Varaktighet:', - 'meeting_editor_screen_meeting_oe_label' => 'Osatt sluttid', - 'meeting_editor_screen_meeting_cc_label' => 'Världsservice kod:', - 'meeting_editor_screen_meeting_cc_advice' => 'Normally leave this field alone (see documentation).', // TODO: translate - 'meeting_editor_screen_meeting_contact_label' => 'Mötets epostkontakt:', - 'meeting_editor_screen_meeting_contact_prompt' => 'Fyll i en epostadress för kontakt and detta möte', - 'meeting_editor_screen_meeting_sb_label' => 'Serviceenhet:', - 'meeting_editor_screen_meeting_sb_default_value' => 'Ingen serviceenhet vald', - 'meeting_editor_screen_meeting_longitude_label' => 'Longitud:', - 'meeting_editor_screen_meeting_longitude_prompt' => 'Fyll i en longitud', - 'meeting_editor_screen_meeting_latitude_label' => 'Latitud:', - 'meeting_editor_screen_meeting_latitude_prompt' => 'fyll i en latitud', - 'meeting_editor_screen_meeting_location_label' => 'plats:', - 'meeting_editor_screen_meeting_location_prompt' => 'Fyll i en plats(ex byggnadens namn)', - 'meeting_editor_screen_meeting_info_label' => 'Extra Info:', - 'meeting_editor_screen_meeting_info_prompt' => 'Fyll i vidare platsinformation', - 'meeting_editor_screen_meeting_street_label' => 'GatuAdress:', - 'meeting_editor_screen_meeting_street_prompt' => 'Fyll i en gatuadress', - 'meeting_editor_screen_meeting_neighborhood_label' => 'Närområde:', - 'meeting_editor_screen_meeting_neighborhood_prompt' => 'Fyll i närområde', - 'meeting_editor_screen_meeting_borough_label' => 'Stadsdel:', - 'meeting_editor_screen_meeting_borough_prompt' => 'Fyll i en stadsdel)', - 'meeting_editor_screen_meeting_city_label' => 'Stad:', - 'meeting_editor_screen_meeting_city_prompt' => 'Fyll i en stad', - 'meeting_editor_screen_meeting_county_label' => 'Land:', - 'meeting_editor_screen_meeting_county_prompt' => 'Fyll i ett land', - 'meeting_editor_screen_meeting_state_label' => 'Län:', - 'meeting_editor_screen_meeting_state_prompt' => 'Fyll i ett län', - 'meeting_editor_screen_meeting_zip_label' => 'Postnummer:', - 'meeting_editor_screen_meeting_zip_prompt' => 'Fyll i postnummer', - 'meeting_editor_screen_meeting_nation_label' => 'Världsdel:', - 'meeting_editor_screen_meeting_nation_prompt' => 'Fyll i en världsdel', - 'meeting_editor_screen_meeting_comments_label' => 'Comments:', - 'meeting_editor_screen_meeting_train_lines_label' => 'Train Lines:', - 'meeting_editor_screen_meeting_bus_lines_label' => 'Bus Lines:', - 'meeting_editor_screen_meeting_phone_meeting_number_label' => 'Phone Meeting Dial-in Number:', - 'meeting_editor_screen_meeting_phone_meeting_number_prompt' => 'Enter the dial-in number for a phone or virtual meeting', - 'meeting_editor_screen_meeting_virtual_meeting_link_label' => 'Virtual Meeting Link:', - 'meeting_editor_screen_meeting_virtual_meeting_link_prompt' => 'Enter the link for a virtual meeting', - 'meeting_editor_screen_meeting_virtual_meeting_additional_info_label' => 'Virtual Meeting Additional Information:', - 'meeting_editor_screen_meeting_virtual_meeting_additional_info_prompt' => 'Enter any additional information for joining the virtual meeting, including directly from the app. For example, if the meeting uses Zoom, "Zoom ID: 456 033 8613, Passcode: 1953" would be appropriate.', - 'meeting_editor_screen_meeting_venue_type' => 'Venue Type:', - 'meeting_editor_screen_meeting_venue_type_inperson' => 'In-Person', - 'meeting_editor_screen_meeting_venue_type_virtual' => 'Virtual', - 'meeting_editor_screen_meeting_venue_type_virtualTC' => 'Virtual (temporarily replacing an in-person)', - 'meeting_editor_screen_meeting_venue_type_hybrid' => 'Hybrid (both in-person and virtual)', - 'meeting_editor_screen_meeting_venue_type_validation' => 'You must select a venue type.', - 'meeting_editor_screen_meeting_virtual_info_missing' => 'Virtual or hybrid meetings must have a Virtual Meeting Link, a Phone Meeting Dial-in Number, or Virtual Meeting Additional Information', - 'meeting_editor_screen_meeting_location_warning' => 'Meeting should have a location (at least a city/town and state/province, or a zip/postal code).', - 'meeting_editor_screen_meeting_address_warning' => 'In-person or hybrid meetings should have a street address.', - 'meeting_editor_screen_meeting_url_validation' => 'Virtual Meeting Link is not a valid URL.', - 'meeting_editor_screen_meeting_url_or_phone_warning' => 'Virtual or hybrid meetings should have either a Virtual Meeting Link or a Phone Meeting Dial-in Number', - 'meeting_editor_screen_meeting_additional_warning' => 'Please also fill in Virtual Meeting Additional Information if there is a Virtual Meeting Link.', - 'meeting_editor_screen_in_person_virtual_info_warning' => 'In-person meetings shouldn\'t have any virtual meeting information.', - 'meeting_editor_screen_meeting_virtual_location_info_warning' => 'Virtual meetings shouldn\'t have a location name or address.', - 'meeting_editor_screen_meeting_validation_warning' => 'There are warnings. Are you sure you want to save anyway? If not, press \'cancel\' and go to the Location tab to see the warnings in place and address them.', - 'meeting_editor_screen_meeting_validation_failed' => 'Unable to save due to input errors. Please go to the Location tab to address them, and then retry saving. Errors: ', - 'meeting_editor_screen_meeting_validation_warnings' => 'Input warnings shown on the Location tab: ', - 'meeting_editor_screen_meeting_contact_name_1_label' => 'Contact 1 Name:', - 'meeting_editor_screen_meeting_contact_email_1_label' => 'Contact 1 Email:', - 'meeting_editor_screen_meeting_contact_phone_1_label' => 'Contact 1 Phone:', - 'meeting_editor_screen_meeting_contact_name_2_label' => 'Contact 2 Name:', - 'meeting_editor_screen_meeting_contact_email_2_label' => 'Contact 2 Email:', - 'meeting_editor_screen_meeting_contact_phone_2_label' => 'Contact 2 Phone:', - 'meeting_editor_screen_meeting_publish_search_prompt' => 'Leta efter:', - 'meeting_editor_screen_meeting_publish_search_pub' => 'Publiserade möten', - 'meeting_editor_screen_meeting_publish_search_unpub' => 'Opubliserade möten', - 'meeting_editor_screen_meeting_visibility_advice' => 'Detta syns inte vid normal mötessökning', - 'meeting_editor_screen_meeting_publish_search_all' => 'Alla möten', - 'meeting_editor_screen_meeting_create_button' => 'Skapa nytt möte', - 'meeting_editor_screen_delete_button' => 'Kassera detta möte', - 'meeting_editor_screen_delete_button_confirm' => 'Är du säker på att du vill kasta detta möte?', - 'meeting_editor_screen_cancel_button' => 'Ångra', - 'logout' => 'Logga ut (och ta en nypa luft)', - 'meeting_editor_screen_cancel_confirm' => 'Säker på att du vill avsluta? du kommer förlora ev ändringar!', - 'meeting_lookup_failed' => 'Adressökningen misslyckades.', - 'meeting_lookup_failed_not_enough_address_info' => 'Det behövs mer adressinformation', - 'meeting_create_button_name' => 'Spara detta som ett nytt möte', - 'meeting_saved_as_a_copy' => 'Spara en kopia på detta möte', - 'meeting_save_buttonName' => 'Spara ändringar', - 'meeting_editor_tab_bar_basic_tab_text' => 'Grundläggnade', - 'meeting_editor_tab_bar_location_tab_text' => 'Plats', - 'meeting_editor_tab_bar_format_tab_text' => 'MötesFormat', - 'meeting_editor_tab_bar_other_tab_text' => 'Annat', - 'meeting_editor_tab_bar_history_tab_text' => 'Historik', - 'meeting_editor_result_count_format' => '%d Möten funna', - 'meeting_id_label' => 'Mötes ID:', - 'meeting_editor_default_zoom' => '13', - 'meeting_editor_default_weekday' => '2', - 'meeting_editor_default_start_time' => '19:00:00', - 'login_banner' => 'Basic Meeting List Toolbox', - 'login_underbanner' => 'Root Server Administrationssida', - 'login' => 'Användarnamn', - 'password' => 'Lösenord', - 'button' => 'Logga in', - 'cookie' => 'Du måste aktivera "cookies" för att de ska fungera.', - 'noscript' => 'Du måste aktivera javascript!', - 'title' => 'Logga in för att göra ändringar', - 'edit_Meeting_object_not_found' => 'FEL: mötet fanns inte.', - 'edit_Meeting_object_not_changed' => 'FEL: mötet ändrades inte', - 'edit_Meeting_auth_failure' => 'Du har inte rättigheter till att ändra detta möte', - 'not_auth_1' => 'DU SAKNAR RÄTTIGHETER', - 'not_auth_2' => 'Du saknar rättigheter till att adminitrera servern', - 'not_auth_3' => 'Problem med dina uppgifter... Capslock eller slarvpelle?', - 'email_format_bad' => 'Epostadressen du angav var felformaterad. (inge snabelsnok eller liknande)', - 'history_header_format' => '
%sav %s
', - 'history_no_history_available_text' => '

Ingen historik för detta möte

', - 'service_body_editor_disclosure' => 'Serviceenhet Administratör', - 'service_body_change_fader_success_text' => 'Serviceenheten ändrad framgångsrikt.', - 'service_body_change_fader_fail_text' => 'Lyckades inte ändra Serviceenheten ', - 'service_body_editor_screen_sb_id_label' => 'ID:', - 'service_body_editor_screen_sb_name_label' => 'Namn:', - 'service_body_name_default_prompt_text' => 'Fyll i Serviceenhetens namn', - 'service_body_parent_popup_label' => 'Serviceenhetens förälder:', - 'service_body_parent_popup_no_parent_option' => 'Ingen förälder (Top-nivå)', - 'service_body_editor_screen_sb_admin_user_label' => 'Primär Administratör:', - 'service_body_editor_screen_sb_admin_description_label' => 'Beskrivning:', - 'service_body_description_default_prompt_text' => 'Fyll i en beskrivning för serviceenheten', - 'service_body_editor_screen_sb_admin_email_label' => 'Kontakt Serviceenhet (Epost):', - 'service_body_email_default_prompt_text' => 'Fyll i en Epostadress för serviceenheten.', - 'service_body_editor_screen_sb_admin_uri_label' => 'web-adress', - 'service_body_uri_default_prompt_text' => 'Fyll i en web-adress för serviceenheten', - 'service_body_editor_screen_sb_admin_full_editor_label' => 'Redaktörer för hela möteslistan:', - 'service_body_editor_screen_sb_admin_full_editor_desc' => 'Dessa redaktörer kan ändra samtliga möten i möteslistan.', - 'service_body_editor_screen_sb_admin_editor_label' => 'Grundläggande redaktörer:', - 'service_body_editor_screen_sb_admin_editor_desc' => 'Dessa redaktörer kan endast ändringar i en specifik serviceenhet. Bara i opubliserade möten.', - 'service_body_editor_screen_sb_admin_observer_label' => 'Observatörer:', - 'service_body_editor_screen_sb_admin_observer_desc' => 'Dessa kan inte ändra något. Men kan se dold information', - 'service_body_dirty_confirm_text' => 'Du har gjort ändringar i serviceenheten. Vill du lämna och förlora dina ändringar?', - 'service_body_save_button' => 'Spara ändringar i serviceenheten', - 'service_body_create_button' => 'Skapa serviceenhet', - 'service_body_delete_button' => 'Kassera serviceenhet', - 'service_body_delete_perm_checkbox' => 'Kassera serviceenhet permanent', - 'service_body_delete_button_confirm' => 'Säker på att du vill kassera serviceenheten? Make sure that all meetings are either removed or transferred to another service body before performing this function.', - 'service_body_delete_button_confirm_perm' => 'Serviceenheten kasseras nu för gott!', - 'service_body_change_fader_create_success_text' => 'Serviceenhet skapad', - 'service_body_change_fader_create_fail_text' => 'Serviceenheten skapades inte!', - 'service_body_change_fader_delete_success_text' => 'Serviceenheten är nu kasserad', - 'service_body_change_fader_delete_fail_text' => 'Serviceenheten kasserades inte!', - 'service_body_change_fader_fail_no_data_text' => 'Serviceenheten ändrades inte, Eftersom du inte fyllt i någon data!', - 'service_body_change_fader_fail_cant_find_sb_text' => 'Serviceenheten ändrades inte, Eftersom serviceenheten saknas', - 'service_body_change_fader_fail_cant_update_text' => 'Serviceenheten ändrades inte, Eftersom serviceenheten inte uppdaterades', - 'service_body_change_fader_fail_bad_hierarchy' => 'Serviceenheten ändrades inte, För föräldraserviceenheten är under denna Serviceenhet, och kan inte användas', - 'service_body_cancel_button' => 'återställ', - 'service_body_editor_type_label' => 'Serviceenhet typ:', - 'service_body_editor_type_c_comdef_service_body__GRP__' => 'Grupp', - 'service_body_editor_type_c_comdef_service_body__COP__' => 'Co-Op', - 'service_body_editor_type_c_comdef_service_body__ASC__' => 'Distrikt', - 'service_body_editor_type_c_comdef_service_body__RSC__' => 'Region', - 'service_body_editor_type_c_comdef_service_body__WSC__' => 'World Service', - 'service_body_editor_type_c_comdef_service_body__MAS__' => 'Metro', - 'service_body_editor_type_c_comdef_service_body__ZFM__' => 'Zon', - 'service_body_editor_type_c_comdef_service_body__GSU__' => 'Group Service Unit', - 'service_body_editor_type_c_comdef_service_body__LSU__' => 'Local Service Unit', - 'service_body_editor_screen_helpline_label' => 'Helpline:', - 'service_body_editor_screen_helpline_prompt' => 'Enter The Helpline Telephone Number', - 'service_body_editor_uri_naws_format_text' => 'Ladda ner mötesinfo från denna serviceenhet i en NAWS kompatibel fil ', - 'edit_Meeting_meeting_id' => 'Mötes ID:', - 'service_body_editor_create_new_sb_option' => 'Skapa en ny serviceenhet', - 'service_body_editor_screen_world_cc_label' => 'NAWS kod:', - 'service_body_editor_screen_world_cc_prompt' => 'Fyll i NAWS kod', - 'user_editor_disclosure' => 'Användar Administration', - 'user_editor_create_new_user_option' => 'Skapa en användare', - 'user_editor_screen_sb_id_label' => 'ID:', - 'user_editor_account_login_label' => 'Användarnamn:', - 'user_editor_login_default_text' => 'Fyll i användarnamn', - 'user_editor_account_type_label' => 'Användaren är en:', - 'user_editor_user_owner_label' => 'Owned By: ', // TODO translate - 'user_editor_account_type_1' => 'Server Administratör', - 'user_editor_account_type_2' => 'Serviceenhets Administratör', - 'user_editor_account_type_3' => 'Serviceenhet Redaktör', - 'user_editor_account_type_5' => 'Serviceenhet observatör', - 'user_editor_account_type_4' => 'Inaktivera användare', - 'user_editor_account_name_label' => 'Användarnamn:', - 'user_editor_name_default_text' => 'Fyll i användarnamn', - 'user_editor_account_description_label' => 'Beskrivning:', - 'user_editor_description_default_text' => 'Fyll i beskrivning för användare', - 'user_editor_account_email_label' => 'E-post:', - 'user_editor_email_default_text' => 'Fyll i E-post för användaren:', - 'user_change_fader_success_text' => 'Användaren ändrad', - 'user_change_fader_fail_text' => 'Användaren ändrades inte!', - 'user_change_fader_create_success_text' => 'Användaren skapades', - 'user_change_fader_create_fail_text' => 'Användaren skapades inte!', - 'user_change_fader_create_fail_already_exists' => 'A Login For The User That You Are Trying To Create Already Exists.', - 'user_change_fader_delete_success_text' => 'Användaren kasserad', - 'user_change_fader_delete_fail_text' => 'Användaren kasserades inte!', - 'user_save_button' => 'Spara ändringar för användaren', - 'user_create_button' => 'Skapa ny användare', - 'user_cancel_button' => 'återställ', - 'user_delete_button' => 'Kassera denna användare', - 'user_delete_perm_checkbox' => 'Kassera denna användare permanent', - 'user_password_label' => 'ändra lösenord till:', - 'user_new_password_label' => 'lösenord:', - 'user_password_default_text' => 'Låt denna vara såvida du inte önskar ändra lösenordet', - 'user_new_password_default_text' => 'Ange lösenord för den nya användaren!', - 'user_dirty_confirm_text' => 'Du har gjort ändringar för användaren, vill du lämna och bli av med ändringarna?', - 'user_delete_button_confirm' => 'Vill du kassera användaren?', - 'user_delete_button_confirm_perm' => 'Användaren kasseras nu permanent!', - 'user_create_password_alert_text' => 'Ange ett lösenord', - 'user_change_fader_fail_no_data_text' => 'Användaren ändrades inte, Ingen data angavs', - 'user_change_fader_fail_cant_find_sb_text' => 'Användaren ändrades inte, Användaren finns inte', - 'user_change_fader_fail_cant_update_text' => 'Användaren ändrades inte, Användaren uppdaterades inte', - 'format_editor_disclosure' => 'MötesFormat Administration', - 'format_change_fader_change_success_text' => 'Mötesformatet ändrades', - 'format_change_fader_change_fail_text' => 'Mötesformatet ändrades inte!', - 'format_change_fader_create_success_text' => 'Mötesformat skapat', - 'format_change_fader_create_fail_text' => 'Mötesformatet skapades inte!', - 'format_change_fader_delete_success_text' => 'Mötesformatet kasserades', - 'format_change_fader_delete_fail_text' => 'Mötesformatet kasserades inte!', - 'format_change_fader_fail_no_data_text' => 'Mötesformatet ändrades inte, Inge data angivet', - 'format_change_fader_fail_cant_find_sb_text' => 'Mötesformatet ändrades inte, Mötesformatet hittades inte', - 'format_change_fader_fail_cant_update_text' => 'Mötesformatet ändrades inte, För mötesformatet uppdaterades inte', - 'format_editor_name_default_text' => 'Ange en kort beskrivning', - 'format_editor_description_default_text' => 'Ange en utförlig beskrivning', - 'format_editor_create_format_button_text' => 'skapa nytt mötesformat', - 'format_editor_cancel_create_format_button_text' => 'ångra', - 'format_editor_create_this_format_button_text' => 'Skapa mötesformat', - 'format_editor_change_format_button_text' => 'ändra mötesformat', - 'format_editor_delete_format_button_text' => 'Kassera mötesformat', - 'format_editor_reset_format_button_text' => 'återställ', - 'need_refresh_message_fader_text' => 'Du bör uppdatera sidan innan du använder denna sektion', - 'need_refresh_message_alert_text' => 'Eftersom du gjort ändringar i serviceenhets administrationen, användar administrationen eller mötesformat administrationen, är det möjligt att information i denna sektion är felaktig, Så logga in och ut så blir allt fint', - 'format_editor_delete_button_confirm' => 'är du säker på att du vill kassera detta mötesformat?', - 'format_editor_delete_button_confirm_perm' => 'Mötesformatet kommer kasseras permanent!', - 'format_editor_missing_key' => 'This format should have an entry for every language (at least a key).', // TODO: translate - 'format_editor_reserved_key' => 'This key is reserved for a venue type format - please use something different.', // TODO: translate - 'min_password_length_string' => 'Lösenordet måste vara minst %d tecken långt!', - 'AJAX_Auth_Failure' => 'Tillträde nekas. Det kan vara problem med serverinställningar.', - 'Maps_API_Key_Warning' => 'There is a problem with the Google Maps API Key.', - 'Observer_Link_Text' => 'Meeting Browser', - 'Data_Transfer_Link_Text' => 'Import Meeting Data (WARNING: Replaces Current Data!)', - 'MapsURL' => 'https://maps.google.com/maps?q=##LAT##,##LONG##+(##NAME##)&ll=##LAT##,##LONG##', - 'hidden_value' => 'Cannot Display Data -Unauthorized', - 'Value_Prompts' => array( - 'id_bigint' => 'Meeting ID', - 'worldid_mixed' => 'World Services ID', - 'service_body' => 'Service Body', - 'service_bodies' => 'Service Bodies', - 'weekdays' => 'Weekdays', - 'weekday' => 'Meeting Gathers Every', - 'start_time' => 'Meeting Starts at', - 'duration_time' => 'Meeting Lasts', - 'location' => 'Location', - 'duration_time_hour' => 'Hour', - 'duration_time_hours' => 'Hours', - 'duration_time_minute' => 'Minute', - 'duration_time_minutes' => 'Minutes', - 'lang_enum' => 'Language', - 'formats' => 'Formats', - 'distance' => 'Distance from Center', - 'generic' => 'NA Meeting', - 'close_title' => 'Close This Meeting Detail Window', - 'close_text' => 'Close Window', - 'map_alt' => 'Map to Meeting', - 'map' => 'Follow This Link for A Map', - 'title_checkbox_unpub_meeting' => 'This meeting is unpublished. It cannot be seen by regular searches.', - 'title_checkbox_copy_meeting' => 'This meeting is a duplicate of another meeting. It is also unpublished. It cannot be seen by regular searches.' - ), - 'world_format_codes_prompt' => 'Naws mötesformat:', - 'world_format_codes' => array( - '' => 'Ingen', - 'OPEN' => 'Öppet möte', - 'CLOSED' => 'Slutet möte', - 'WCHR' => 'Rullstolsvänlig lokal', - 'BEG' => 'Nykomling', - 'BT' => 'Basic Text möte', - 'CAN' => 'Ljusmöte', - 'CPT' => '12 Konsept möte', - 'CW' => 'Barn välkomna', - 'DISC' => 'Diskutionsmöte', - 'GL' => 'Gay/Lesbiskt', - 'IP' => 'IP Studie', - 'IW' => 'Det fungerar Studie', - 'JFT' => 'Bara för idag Studie', - 'LC' => 'Living Clean Studie', - 'LIT' => 'Literatur Studie', - 'M' => 'Mansmöte', - 'MED' => 'Meditationsmöte', - 'QA' => 'Frågor och svar', - 'RA' => 'Ej publikt möte', - 'NS' => 'Non-Smoking', - 'S-D' => 'Speaker/Discussion', // TODO translate - 'SMOK' => 'Rökare', - 'SPK' => 'Talarmöte', - 'STEP' => 'Stegmöte', - 'SWG' => 'Stegarnetsguiden studie', - 'TOP' => 'Temamöte', - 'TRAD' => 'Traditionsmöte', - 'VAR' => 'Blandad mötesform', - 'W' => 'Kvinnomöte', - 'Y' => 'Ungdomsmöte', - 'LANG' => 'Alternativt språk', - 'GP' => 'Guiding Principles', // TODO translate - 'NC' => 'No Children', // TODO translate - 'CH' => 'Closed Holidays', // TODO translate - 'VM' => 'Virtual', // TODO translate - 'HYBR' => 'Virtual and In-Person', // TODO translate - 'TC' => 'Temporarily Closed Facility', // TODO translate - 'SPAD' => 'Spiritual Principle a Day', // TODO translate - ), - 'format_type_prompt' => 'Format Type:', // TODO: Translate - 'format_type_codes' => array( - '' => 'None', // TODO: Translate - 'FC1' => 'Meeting Format (Speaker, Book Study, etc.)', // TODO: Translate - 'FC2' => 'Location Code (Wheelchair Accessible, Limited Parking, etc.)', // TODO: Translate - 'FC3' => 'Common Needs and Restrictions (Mens Meeting, LGTBQ, No Children, etc.)', // TODO: Translate - 'O' => 'Attendance by non-addicts (Open, Closed)', // TODO: Translate - 'LANG' => 'Language', // TODO: TRANSLATE - 'ALERT' => 'Format should be especially prominent (Clean requirement, etc.)',// TODO: Translate - ), - 'cookie_monster' => 'Denna sida använder cookies för att minnas ditt språkval.', - 'main_prompts' => array( - 'id_bigint' => 'ID', - 'worldid_mixed' => 'World ID', - 'shared_group_id_bigint' => 'Unused', - 'service_body_bigint' => 'Service Body ID', - 'weekday_tinyint' => 'Weekday', - 'venue_type' => 'Venue Type', - 'start_time' => 'Start Time', - 'duration_time' => 'Duration', - 'time_zone' => 'Time Zone', - 'formats' => 'Formats', - 'lang_enum' => 'Language', - 'longitude' => 'Longitude', - 'latitude' => 'Latitude', - 'published' => 'Published', - 'email_contact' => 'Email Contact', - ), - 'check_all' => 'Check All', - 'uncheck_all' => 'Uncheck All', - 'automatically_calculated_on_save' => 'Automatically calculated on save.' -); - -$email_contact_strings = array( - 'meeting_contact_form_subject_format' => "[MEETING LIST CONTACT] %s", - 'meeting_contact_message_format' => "%s\n--\nThis message concerns the meeting named \"%s\", which meets at %s, on %s.\nBrowser Link: %s\nEdit Link: %s\nIt was sent directly from the meeting list web server, and the sender is not aware of your email address.\nPlease be aware that replying will expose your email address.\nIf you use \"Reply All\", and there are multiple email recipients, you may expose other people's email addresses.\nPlease respect people's privacy and anonymity; including the original sender of this message." -); - -$change_type_strings = array( - '__THE_MEETING_WAS_CHANGED__' => 'The meeting was changed.', - '__THE_MEETING_WAS_CREATED__' => 'The meeting was created.', - '__THE_MEETING_WAS_DELETED__' => 'The meeting was deleted.', - '__THE_MEETING_WAS_ROLLED_BACK__' => 'The meeting was rolled back to a previous version.', - - '__THE_FORMAT_WAS_CHANGED__' => 'The format was changed.', - '__THE_FORMAT_WAS_CREATED__' => 'The format was created.', - '__THE_FORMAT_WAS_DELETED__' => 'The format was deleted.', - '__THE_FORMAT_WAS_ROLLED_BACK__' => 'The format was rolled back to a previous version.', - - '__THE_SERVICE_BODY_WAS_CHANGED__' => 'The service body was changed.', - '__THE_SERVICE_BODY_WAS_CREATED__' => 'The service body was created.', - '__THE_SERVICE_BODY_WAS_DELETED__' => 'The service body was deleted.', - '__THE_SERVICE_BODY_WAS_ROLLED_BACK__' => 'The service body was rolled back to a previous version.', - - '__THE_USER_WAS_CHANGED__' => 'The user was changed.', - '__THE_USER_WAS_CREATED__' => 'The user was created.', - '__THE_USER_WAS_DELETED__' => 'The user was deleted.', - '__THE_USER_WAS_ROLLED_BACK__' => 'The user was rolled back to a previous version.', - - '__BY__' => 'by', - '__FOR__' => 'for' -); - -$detailed_change_strings = array( - 'was_changed_from' => 'was changed from', - 'to' => 'to', - 'was_changed' => 'was changed', - 'was_added_as' => 'was added as', - 'was_deleted' => 'was deleted', - 'was_published' => 'The meeting was published', - 'was_unpublished' => 'The meeting was unpublished', - 'formats_prompt' => 'The meeting format', - 'duration_time' => 'The meeting duration', - 'start_time' => 'The meeting start time', - 'longitude' => 'The meeting longitude', - 'latitude' => 'The meeting latitude', - 'sb_prompt' => 'The meeting changed its Service Body from', - 'id_bigint' => 'The meeting ID', - 'lang_enum' => 'The meeting language', - 'worldid_mixed' => 'The World Committee Code', - 'weekday_tinyint' => 'The day of the week on which the meeting gathers', - 'non_existent_service_body' => 'Service Body No Longer Exists', -); - -defined('_END_CHANGE_REPORT') or define('_END_CHANGE_REPORT', '.'); diff --git a/src/legacy/local_server/server_admin/main_console.php b/src/legacy/local_server/server_admin/main_console.php deleted file mode 100644 index d1ee87a61..000000000 --- a/src/legacy/local_server/server_admin/main_console.php +++ /dev/null @@ -1,22 +0,0 @@ -. -*/ -defined('BMLT_EXEC') or die('Cannot Execute Directly'); // Makes sure that this file is in the correct context. -require_once(dirname(__FILE__).'/c_comdef_admin_main_console.class.php'); - -$console_object = new c_comdef_admin_main_console($http_vars); -echo $console_object instanceof c_comdef_admin_main_console ? $console_object->return_main_console_html() : 'ERROR'; diff --git a/src/legacy/local_server/server_admin/server_admin_javascript.js b/src/legacy/local_server/server_admin/server_admin_javascript.js deleted file mode 100644 index bcc2eefd7..000000000 --- a/src/legacy/local_server/server_admin/server_admin_javascript.js +++ /dev/null @@ -1,6202 +0,0 @@ -/* - This file is part of the Basic Meeting List Toolbox (BMLT). - - Find out more at: https://bmlt.app - - BMLT is free software: you can redistribute it and/or modify - it under the terms of the MIT License. - - BMLT is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - MIT License for more details. - - You should have received a copy of the MIT License along with this code. - If not, see . -*/ -/******************************************************************************************** -*######################################### MAIN CODE #######################################* -********************************************************************************************/ - -function BMLT_Server_Admin() -{ - // #mark - - // #mark ########## Class Declaration ########## - // #mark - - - /************************************************************************************//** - * DATA MEMBERS * - ****************************************************************************************/ - var m_server_admin_panel_shown = null; ///< This will be true if the "Server Administration" panel is exposed. - var m_account_panel_shown = null; ///< This will be true if the "My Account" panel is exposed. - var m_search_specifier_shown = null; ///< This is true, if the meeting search specifier form is shown. - var m_meeting_editor_panel_shown = null; ///< This will be true if the "Edit Meetings" panel is exposed. - var m_service_body_editor_panel_shown = null; ///< This is true, if the Service Body Editor is shown. - var m_ajax_request_in_progress = null; ///< This is any AJAX request currently under way. - var m_success_fade_duration = null; ///< Number of milliseconds for a success fader. - var m_failure_fade_duration = null; ///< Number of milliseconds for a failure fader. - var m_search_results = null; ///< This will contain any meeting search results. - var m_meeting_results_container_div = null; ///< This will hold any search result display elements (allows easy disposal) - var m_editing_window_open = null; ///< If there is a meeting editor open, it is recorded here. There can only be one... - var m_user_editor_panel_shown = null; ///< Set to true, if the user editor is open. - var m_warn_user_to_refresh = null; ///< If this is true, then a warning alert will be shown to the user. - var m_format_editor_table_rows = null; ///< This is used to track the number of rows in the format editor table. - - this.validationMessageTypes = { - "ERROR": "error", - "WARN": "warn" - } - - /************************************************************************************//** - * METHODS * - ****************************************************************************************/ - - // #mark - - // #mark Affects All Sections - // #mark - - - /************************************************************************************//** - * \brief If one of the upper sections has been edited, it can affect the Account, * - * Meeting or Service Body sections. In this case, the user needs to log out, * - * then back in again (or refresh the page, but signing out is easier to * - * explain). This sets an orange fader in each affected section, and also sets * - * the trigger for an alert that explains it. * - ****************************************************************************************/ - this.setWarningFaders = function () { - if ( document.getElementById('bmlt_admin_fader_service_body_editor_warn_div') ) { - document.getElementById('bmlt_admin_fader_service_body_editor_warn_div').className = 'bmlt_admin_fader_div'; - }; - - if ( document.getElementById('bmlt_admin_fader_meeting_editor_warn_div') ) { - document.getElementById('bmlt_admin_fader_meeting_editor_warn_div').className = 'bmlt_admin_fader_div'; - }; - - if ( document.getElementById('bmlt_admin_fader_account_warn_div') ) { - document.getElementById('bmlt_admin_fader_account_warn_div').className = 'bmlt_admin_fader_div'; - }; - - this.m_warn_user_to_refresh = true; - }; - - /************************************************************************************//** - * \brief This displays that alert. * - ****************************************************************************************/ - this.showWarningAlert = function () { - if ( this.m_warn_user_to_refresh ) { // Only if needed. - alert(g_need_refresh_message_alert_text); - this.m_warn_user_to_refresh = false; - }; - }; - - // #mark - - // #mark Text Item Handlers - // #mark - - - /************************************************************************************//** - * \brief When a text input (either or