Stable release of v2.0.9

Adds create tags on front-end. Adds update tags on front-end. Adds delete of tags on front-end. Improves verse view in note, and tag modal. Other bug fixes.
This commit is contained in:
Robot 2023-08-02 21:39:24 +02:00
parent fb7b0ca373
commit e14b888e28
Signed by: Robot
GPG Key ID: 14DECD44E7E1BB95
41 changed files with 629 additions and 183 deletions

View File

@ -45,4 +45,12 @@
# v2.0.8
- Adds easy option to update book names in the back-end.
- Adds easy option to sync translations details in the back-end.
- Adds easy option to sync translations details in the back-end.
# v2.0.9
- Adds create tags on front-end.
- Adds update tags on front-end.
- Adds delete of tags on front-end.
- Improves verse view in note, and tag modal.
- Other bug fixes.

View File

@ -1,4 +1,4 @@
# Get Bible (2.0.8)
# Get Bible (2.0.9)
![Get Bible image](https://git.vdm.dev/getBible/joomla-component/raw/branch/master/admin/assets/images/vdm-component.jpg "GetBible")
@ -18,32 +18,32 @@ In essence, The Bible for Joomla is designed to transform how the Word of God is
+ *Author*: [Llewellyn van der Merwe](mailto:joomla@vdm.io)
+ *Name*: [Get Bible](https://getbible.net)
+ *First Build*: 3rd December, 2015
+ *Last Build*: 1st August, 2023
+ *Version*: 2.0.8
+ *Last Build*: 2nd August, 2023
+ *Version*: 2.0.9
+ *Copyright*: Copyright (C) 2015. All Rights Reserved
+ *License*: GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html
## Build Time
**545 Hours** or **68 Eight Hour Days** (actual time the author saved -
**547 Hours** or **68 Eight Hour Days** (actual time the author saved -
due to [Automated Component Builder](https://www.joomlacomponentbuilder.com))
> (if creating a folder and file took **5 seconds** and writing one line of code took **10 seconds**,
> never making one mistake or taking any coffee break.)
+ *Line count*: **195153**
+ *File count*: **1699**
+ *Line count*: **195918**
+ *File count*: **1700**
+ *Folder count*: **162**
**359 Hours** or **45 Eight Hour Days** (the actual time the author spent)
**360 Hours** or **45 Eight Hour Days** (the actual time the author spent)
> (with the following break down:
> **debugging @136hours** = codingtime / 4;
> **debugging @137hours** = codingtime / 4;
> **planning @78hours** = codingtime / 7;
> **mapping @54hours** = codingtime / 10;
> **mapping @55hours** = codingtime / 10;
> **office @91hours** = codingtime / 6;)
**904 Hours** or **113 Eight Hour Days**
**907 Hours** or **113 Eight Hour Days**
(a total of the realistic time frame for this project)
> (if creating a folder and file took **5 seconds** and writing one line of code took **10 seconds**,

View File

@ -1,4 +1,4 @@
# Get Bible (2.0.8)
# Get Bible (2.0.9)
![Get Bible image](https://git.vdm.dev/getBible/joomla-component/raw/branch/master/admin/assets/images/vdm-component.jpg "GetBible")
@ -18,32 +18,32 @@ In essence, The Bible for Joomla is designed to transform how the Word of God is
+ *Author*: [Llewellyn van der Merwe](mailto:joomla@vdm.io)
+ *Name*: [Get Bible](https://getbible.net)
+ *First Build*: 3rd December, 2015
+ *Last Build*: 1st August, 2023
+ *Version*: 2.0.8
+ *Last Build*: 2nd August, 2023
+ *Version*: 2.0.9
+ *Copyright*: Copyright (C) 2015. All Rights Reserved
+ *License*: GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html
## Build Time
**545 Hours** or **68 Eight Hour Days** (actual time the author saved -
**547 Hours** or **68 Eight Hour Days** (actual time the author saved -
due to [Automated Component Builder](https://www.joomlacomponentbuilder.com))
> (if creating a folder and file took **5 seconds** and writing one line of code took **10 seconds**,
> never making one mistake or taking any coffee break.)
+ *Line count*: **195153**
+ *File count*: **1699**
+ *Line count*: **195918**
+ *File count*: **1700**
+ *Folder count*: **162**
**359 Hours** or **45 Eight Hour Days** (the actual time the author spent)
**360 Hours** or **45 Eight Hour Days** (the actual time the author spent)
> (with the following break down:
> **debugging @136hours** = codingtime / 4;
> **debugging @137hours** = codingtime / 4;
> **planning @78hours** = codingtime / 7;
> **mapping @54hours** = codingtime / 10;
> **mapping @55hours** = codingtime / 10;
> **office @91hours** = codingtime / 6;)
**904 Hours** or **113 Eight Hour Days**
**907 Hours** or **113 Eight Hour Days**
(a total of the realistic time frame for this project)
> (if creating a folder and file took **5 seconds** and writing one line of code took **10 seconds**,

View File

@ -13,6 +13,7 @@
<action name="core.edit.own" title="JACTION_EDITOWN" description="JACTION_EDITOWN_COMPONENT_DESC" />
<action name="core.edit.created_by" title="COM_GETBIBLE_EDIT_CREATED_BY" description="COM_GETBIBLE_EDIT_CREATED_BY_DESC" />
<action name="core.edit.created" title="COM_GETBIBLE_EDIT_CREATED_DATE" description="COM_GETBIBLE_EDIT_CREATED_DATE_DESC" />
<action name="book.update_chapters_names" title="COM_GETBIBLE_BOOK_UPDATE_CHAPTERS_NAMES_BUTTON_ACCESS" description="COM_GETBIBLE_BOOK_UPDATE_CHAPTERS_NAMES_BUTTON_ACCESS_DESC" />
<action name="book.access" title="COM_GETBIBLE_BOOKS_ACCESS" description="COM_GETBIBLE_BOOKS_ACCESS_DESC" />
<action name="book.batch" title="COM_GETBIBLE_BOOKS_BATCH_USE" description="COM_GETBIBLE_BOOKS_BATCH_USE_DESC" />
<action name="book.create" title="COM_GETBIBLE_BOOKS_CREATE" description="COM_GETBIBLE_BOOKS_CREATE_DESC" />

View File

@ -20,6 +20,8 @@ defined('_JEXEC') or die('Restricted access');
use Joomla\CMS\MVC\Controller\AdminController;
use Joomla\Utilities\ArrayHelper;
use VDM\Joomla\Utilities\ArrayHelper as UtilitiesArrayHelper;
use VDM\Joomla\GetBible\Factory;
/**
* Books Admin Controller
@ -49,4 +51,58 @@ class GetbibleControllerBooks extends AdminController
{
return parent::getModel($name, $prefix, $config);
}
public function updateChaptersNames()
{
// Check for request forgeries
JSession::checkToken() or die(Text::_('JINVALID_TOKEN'));
// check if export is allowed for this user.
$user = JFactory::getUser();
if ($user->authorise('book.update_chapters_names', 'com_getbible'))
{
// Get the input
$input = JFactory::getApplication()->input;
$pks = $input->post->get('cid', array(), 'array');
// Sanitize the input
JArrayHelper::toInteger($pks);
// check if there is any selections
$number = UtilitiesArrayHelper::check($pks);
if (!$number)
{
// Redirect to the list screen with error.
$message = JText::_('COM_GETBIBLE_NO_BOOK_WAS_SELECTED_PLEASE_MAKE_A_SELECTION_AND_TRY_AGAIN');
$this->setRedirect(JRoute::_('index.php?option=com_getbible&view=books', false), $message, 'error');
return;
}
elseif (Factory::_('GetBible.Watcher.Chapter')->names($pks))
{
// Redirect to the list screen with success.
$message = array();
$message[] = '<h1>' . JText::_('COM_GETBIBLE_UPDATE_COMPLETED') . '</h1>';
// get the data to export
if ($number == 1)
{
$message[] = '<p>' . JText::_('COM_GETBIBLE_THE_CHAPTER_NAMES_OF_THE_BOOK_WERE_SUCCESSFULLY_UPDATED_AND_THEY_ARE_NOW_IN_SYNC_WITH_THE_GETBIBLE_API') . '</p>';
}
else
{
$message[] = '<p>' . JText::_('COM_GETBIBLE_THE_CHAPTER_NAMES_OF_THE_SELECTED_BOOKS_WERE_SUCCESSFULLY_UPDATED_AND_THEY_ARE_NOW_IN_SYNC_WITH_THE_GETBIBLE_API') . '</p>';
}
$this->setRedirect(JRoute::_('index.php?option=com_getbible&view=books', false), implode('', $message), 'Success');
return;
}
}
else
{
// Redirect to the list screen with error.
$message = JText::_('COM_GETBIBLE_YOU_DO_NOT_HAVE_PERMISSION_TO_UPDATE_THE_CHAPTER_NAMES_PLEASE_CONTACT_YOUR_SYSTEM_ADMINISTRATOR_FOR_MORE_HELP');
$this->setRedirect(JRoute::_('index.php?option=com_getbible&view=books', false), $message, 'error');
return;
}
// Redirect to the list screen with error.
$message = JText::_('COM_GETBIBLE_UPDATE_FAILED_PLEASE_TRY_AGAIN_LATTER');
$this->setRedirect(JRoute::_('index.php?option=com_getbible&view=books', false), $message, 'error');
return;
}
}

View File

@ -59,7 +59,7 @@ class GetbibleControllerTranslations extends AdminController
// check if export is allowed for this user.
$user = JFactory::getUser();
if ($user->authorise('translation.update_translations_details', 'com_getbible') && $user->authorise('core.export', 'com_getbible'))
if ($user->authorise('translation.update_translations_details', 'com_getbible'))
{
if (Factory::_('GetBible.Watcher.Translation')->translations())
{
@ -91,7 +91,7 @@ class GetbibleControllerTranslations extends AdminController
// check if export is allowed for this user.
$user = JFactory::getUser();
if ($user->authorise('translation.update_book_names', 'com_getbible') && $user->authorise('core.export', 'com_getbible'))
if ($user->authorise('translation.update_book_names', 'com_getbible'))
{
// Get the input
$input = JFactory::getApplication()->input;

View File

@ -90,6 +90,8 @@ COM_GETBIBLE_BOOK_SHA_DESCRIPTION="Enter some checksum sha"
COM_GETBIBLE_BOOK_SHA_LABEL="Checksum"
COM_GETBIBLE_BOOK_SHA_MESSAGE="Error! Please add some checksum sha here."
COM_GETBIBLE_BOOK_STATUS="Status"
COM_GETBIBLE_BOOK_UPDATE_CHAPTERS_NAMES_BUTTON_ACCESS="Book Update Chapters Names Button Access"
COM_GETBIBLE_BOOK_UPDATE_CHAPTERS_NAMES_BUTTON_ACCESS_DESC="Allows the users in this group to access the update chapters names button."
COM_GETBIBLE_BOOK_VERSION_DESC="A count of the number of times this Book has been revised."
COM_GETBIBLE_BOOK_VERSION_LABEL="Version"
COM_GETBIBLE_CHAPTER="Chapter"
@ -762,6 +764,7 @@ COM_GETBIBLE_NOTE_VERSION_DESC="A count of the number of times this Note has bee
COM_GETBIBLE_NOTE_VERSION_LABEL="Version"
COM_GETBIBLE_NOT_FOUND_OR_ACCESS_DENIED="Not found, or access denied."
COM_GETBIBLE_NO_ACCESS_GRANTED="No Access Granted!"
COM_GETBIBLE_NO_BOOK_WAS_SELECTED_PLEASE_MAKE_A_SELECTION_AND_TRY_AGAIN="No book was selected, please make a selection and try again!"
COM_GETBIBLE_NO_TRANSLATION_WAS_SELECTED_PLEASE_MAKE_A_SELECTION_AND_TRY_AGAIN="No translation was selected, please make a selection and try again!"
COM_GETBIBLE_OPEN_AI_DISABLED="Open AI (disabled)"
COM_GETBIBLE_OPEN_AI_MESSAGE="Open AI Message"
@ -1363,7 +1366,9 @@ COM_GETBIBLE_PUBLISHED="Published"
COM_GETBIBLE_SAVE_SUCCESS="Great! Item successfully saved."
COM_GETBIBLE_SAVE_WARNING="The value already existed so please select another."
COM_GETBIBLE_SELECT_AN_OPTION="Select an option"
COM_GETBIBLE_SESSION_ACTIVE="Session active."
COM_GETBIBLE_SESSION_KEY_COULD_NOT_BE_STORED="Session key could not be stored."
COM_GETBIBLE_SESSION_NOT_ACTIVE="Session not active."
COM_GETBIBLE_SUBMENU_BOOKS="Books"
COM_GETBIBLE_SUBMENU_CHAPTERS="Chapters"
COM_GETBIBLE_SUBMENU_DASHBOARD="Dashboard"
@ -1573,6 +1578,8 @@ COM_GETBIBLE_TAG_VERSION_DESC="A count of the number of times this Tag has been
COM_GETBIBLE_TAG_VERSION_LABEL="Version"
COM_GETBIBLE_THE_BOOK_NAMES_OF_THE_SELECTED_TRANSLATIONS_WERE_SUCCESSFULLY_UPDATED_AND_THEY_ARE_NOW_IN_SYNC_WITH_THE_GETBIBLE_API="The book names of the selected translations were successfully updated, and they are now in sync with the getBible API."
COM_GETBIBLE_THE_BOOK_NAMES_OF_THE_TRANSLATION_WERE_SUCCESSFULLY_UPDATED_AND_THEY_ARE_NOW_IN_SYNC_WITH_THE_GETBIBLE_API="The book names of the translation were successfully updated, and they are now in sync with the getBible API."
COM_GETBIBLE_THE_CHAPTER_NAMES_OF_THE_BOOK_WERE_SUCCESSFULLY_UPDATED_AND_THEY_ARE_NOW_IN_SYNC_WITH_THE_GETBIBLE_API="The chapter names of the book were successfully updated, and they are now in sync with the getBible API."
COM_GETBIBLE_THE_CHAPTER_NAMES_OF_THE_SELECTED_BOOKS_WERE_SUCCESSFULLY_UPDATED_AND_THEY_ARE_NOW_IN_SYNC_WITH_THE_GETBIBLE_API="The chapter names of the selected books were successfully updated, and they are now in sync with the getBible API."
COM_GETBIBLE_THE_NAME_COULD_NOT_BE_UPDATED="The name could not be updated."
COM_GETBIBLE_THE_NAME_HAS_BEEN_UPDATED="The name has been updated."
COM_GETBIBLE_THE_NOTE_WAS_SUCCESSFULLY_CREATED="The note was successfully created."
@ -1773,6 +1780,7 @@ COM_GETBIBLE_TYPE_TAGGED_VERSE="Tagged Verse"
COM_GETBIBLE_TYPE_TRANSLATION="Translation"
COM_GETBIBLE_TYPE_VERSE="Verse"
COM_GETBIBLE_UPDATE_BOOK_NAMES="Update Book Names"
COM_GETBIBLE_UPDATE_CHAPTERS_NAMES="Update Chapters Names"
COM_GETBIBLE_UPDATE_COMPLETED="Update Completed!"
COM_GETBIBLE_UPDATE_FAILED_PLEASE_TRY_AGAIN_LATTER="Update failed, please try again latter!"
COM_GETBIBLE_UPDATE_TRANSLATIONS_DETAILS="Update Translations Details"
@ -1877,4 +1885,5 @@ COM_GETBIBLE_YOU_ARE_CURRENTLY_VIEWING_THE_TRASHED_ITEMS="You are currently view
COM_GETBIBLE_YOU_ARE_CURRENTLY_VIEWING_THE_TRASH_AREA_AND_YOU_DONT_HAVE_ANY_ITEMS_IN_TRASH_AT_THE_MOMENT="You are currently viewing the trash area, and you don't have any items in trash at the moment!"
COM_GETBIBLE_YOU_CAN_DIRECTLY_DOWNLOAD_THE_LATEST_UPDATE_OR_USE_THE_JOOMLA_UPDATE_AREA="You can directly download the latest update, or use the Joomla update area."
COM_GETBIBLE_YOU_DO_NOT_HAVE_PERMISSION_TO_UPDATE_THE_BOOK_NAMES_PLEASE_CONTACT_YOUR_SYSTEM_ADMINISTRATOR_FOR_MORE_HELP="You do not have permission to update the book names, please contact your system administrator for more help."
COM_GETBIBLE_YOU_DO_NOT_HAVE_PERMISSION_TO_UPDATE_THE_CHAPTER_NAMES_PLEASE_CONTACT_YOUR_SYSTEM_ADMINISTRATOR_FOR_MORE_HELP="You do not have permission to update the chapter names, please contact your system administrator for more help."
COM_GETBIBLE_YOU_WILL_HAVE_TO_ENABLE_OPEN_AI_IN_THE_GLOBAL_OPTIONS_OF_YOUR_COMPONENT_SINCE_IT_IS_CURRENTLY_DISABLED="You will have to enable Open AI in the global options of your component, since it is currently disabled."

View File

@ -29,6 +29,8 @@ COM_GETBIBLE_BOOKS_EDIT_STATE="Books Edit State"
COM_GETBIBLE_BOOKS_EDIT_STATE_DESC="Allows the users in this group to update the state of the book"
COM_GETBIBLE_BOOKS_SUBMENU="Books Submenu"
COM_GETBIBLE_BOOKS_SUBMENU_DESC="Allows the users in this group to submenu of book"
COM_GETBIBLE_BOOK_UPDATE_CHAPTERS_NAMES_BUTTON_ACCESS="Book Update Chapters Names Button Access"
COM_GETBIBLE_BOOK_UPDATE_CHAPTERS_NAMES_BUTTON_ACCESS_DESC="Allows the users in this group to access the update chapters names button."
COM_GETBIBLE_CHAPTERS_ACCESS="Chapters Access"
COM_GETBIBLE_CHAPTERS_ACCESS_DESC="Allows the users in this group to access access chapters"
COM_GETBIBLE_CHAPTERS_BATCH_USE="Chapters Batch Use"

View File

@ -154,7 +154,7 @@ class GetbibleModelAjax extends ListModel
else
{
// download link of the latest version
$download = "https://git.vdm.dev/api/v1/repos/joomla/[[[gitea_package_name]]]/archive/" . $tags[0]->name . ".zip?access_token=" . $token;
$download = "https://git.vdm.dev/api/v1/repos/getBible/joomla-component/archive/" . $tags[0]->name . ".zip?access_token=" . $token;
return ['notice' => '<small><span style="color:red;"><span class="icon-warning-circle"></span>' . Text::_('COM_GETBIBLE_OUT_OF_DATE') . '!</span> <a style="color:green;" href="' .
$download . '" title="' . Text::_('COM_GETBIBLE_YOU_CAN_DIRECTLY_DOWNLOAD_THE_LATEST_UPDATE_OR_USE_THE_JOOMLA_UPDATE_AREA') . '">' . Text::_('COM_GETBIBLE_DOWNLOAD_UPDATE') . '!</a></small>'];

View File

@ -279,13 +279,16 @@ class GetbibleModelBooks extends ListModel
}
// Add the list ordering clause.
$orderCol = $this->state->get('list.ordering', 'a.id');
$orderDirn = $this->state->get('list.direction', 'desc');
$orderCol = $this->state->get('list.ordering', 'g.translation');
$orderDirn = $this->state->get('list.direction', 'asc');
if ($orderCol != '')
{
$query->order($db->escape($orderCol . ' ' . $orderDirn));
}
// Add a permanent list ordering.
$query->order($db->escape('a.nr asc'));
return $query;
}

View File

@ -333,13 +333,19 @@ class GetbibleModelChapters extends ListModel
}
// Add the list ordering clause.
$orderCol = $this->state->get('list.ordering', 'a.id');
$orderDirn = $this->state->get('list.direction', 'desc');
$orderCol = $this->state->get('list.ordering', 'g.translation');
$orderDirn = $this->state->get('list.direction', 'asc');
if ($orderCol != '')
{
$query->order($db->escape($orderCol . ' ' . $orderDirn));
}
// Add a permanent list ordering.
$query->order($db->escape('a.book_nr asc'));
// Add a permanent list ordering.
$query->order($db->escape('a.chapter asc'));
return $query;
}

View File

@ -61,7 +61,7 @@
label="COM_CONTENT_LIST_FULL_ORDERING"
description="COM_CONTENT_LIST_FULL_ORDERING_DESC"
onchange="this.form.submit();"
default="a.id DESC"
default="g.translation asc"
validate="options"
>
<option value="">JGLOBAL_SORT_BY</option>

View File

@ -63,7 +63,7 @@
label="COM_CONTENT_LIST_FULL_ORDERING"
description="COM_CONTENT_LIST_FULL_ORDERING_DESC"
onchange="this.form.submit();"
default="a.id DESC"
default="g.translation asc"
validate="options"
>
<option value="">JGLOBAL_SORT_BY</option>

View File

@ -47,7 +47,7 @@
label="COM_CONTENT_LIST_FULL_ORDERING"
description="COM_CONTENT_LIST_FULL_ORDERING_DESC"
onchange="this.form.submit();"
default="a.id DESC"
default="a.language asc"
validate="options"
>
<option value="">JGLOBAL_SORT_BY</option>

View File

@ -68,7 +68,7 @@
label="COM_CONTENT_LIST_FULL_ORDERING"
description="COM_CONTENT_LIST_FULL_ORDERING_DESC"
onchange="this.form.submit();"
default="a.id DESC"
default="g.translation asc"
validate="options"
>
<option value="">JGLOBAL_SORT_BY</option>

View File

@ -283,13 +283,16 @@ class GetbibleModelTranslations extends ListModel
}
// Add the list ordering clause.
$orderCol = $this->state->get('list.ordering', 'a.id');
$orderDirn = $this->state->get('list.direction', 'desc');
$orderCol = $this->state->get('list.ordering', 'a.language');
$orderDirn = $this->state->get('list.direction', 'asc');
if ($orderCol != '')
{
$query->order($db->escape($orderCol . ' ' . $orderDirn));
}
// Add a permanent list ordering.
$query->order($db->escape('a.translation asc'));
return $query;
}

View File

@ -304,13 +304,22 @@ class GetbibleModelVerses extends ListModel
}
// Add the list ordering clause.
$orderCol = $this->state->get('list.ordering', 'a.id');
$orderDirn = $this->state->get('list.direction', 'desc');
$orderCol = $this->state->get('list.ordering', 'g.translation');
$orderDirn = $this->state->get('list.direction', 'asc');
if ($orderCol != '')
{
$query->order($db->escape($orderCol . ' ' . $orderDirn));
}
// Add a permanent list ordering.
$query->order($db->escape('a.book_nr asc'));
// Add a permanent list ordering.
$query->order($db->escape('a.chapter asc'));
// Add a permanent list ordering.
$query->order($db->escape('a.verse asc'));
return $query;
}

View File

@ -0,0 +1 @@

View File

@ -47,8 +47,8 @@ class GetbibleViewBooks extends HtmlView
// Load the active filters.
$this->activeFilters = $this->get('ActiveFilters');
// Add the list ordering clause.
$this->listOrder = $this->escape($this->state->get('list.ordering', 'a.id'));
$this->listDirn = $this->escape($this->state->get('list.direction', 'DESC'));
$this->listOrder = $this->escape($this->state->get('list.ordering', 'g.translation'));
$this->listDirn = $this->escape($this->state->get('list.direction', 'asc'));
$this->saveOrder = $this->listOrder == 'a.ordering';
// set the return here value
$this->return_here = urlencode(base64_encode((string) JUri::getInstance()));
@ -132,6 +132,11 @@ class GetbibleViewBooks extends HtmlView
$dhtml = $layout->render(array('title' => $title));
$bar->appendButton('Custom', $dhtml, 'batch');
}
if ($this->user->authorise('book.update_chapters_names', 'com_getbible'))
{
// add Update Chapters Names button.
JToolBarHelper::custom('books.updateChaptersNames', 'generic custom-button-updatechaptersnames', '', 'COM_GETBIBLE_UPDATE_CHAPTERS_NAMES', 'true');
}
if ($this->state->get('filter.published') == -2 && ($this->canState && $this->canDelete))
{

View File

@ -47,8 +47,8 @@ class GetbibleViewChapters extends HtmlView
// Load the active filters.
$this->activeFilters = $this->get('ActiveFilters');
// Add the list ordering clause.
$this->listOrder = $this->escape($this->state->get('list.ordering', 'a.id'));
$this->listDirn = $this->escape($this->state->get('list.direction', 'DESC'));
$this->listOrder = $this->escape($this->state->get('list.ordering', 'g.translation'));
$this->listDirn = $this->escape($this->state->get('list.direction', 'asc'));
$this->saveOrder = $this->listOrder == 'a.ordering';
// set the return here value
$this->return_here = urlencode(base64_encode((string) JUri::getInstance()));

View File

@ -47,8 +47,8 @@ class GetbibleViewTranslations extends HtmlView
// Load the active filters.
$this->activeFilters = $this->get('ActiveFilters');
// Add the list ordering clause.
$this->listOrder = $this->escape($this->state->get('list.ordering', 'a.id'));
$this->listDirn = $this->escape($this->state->get('list.direction', 'DESC'));
$this->listOrder = $this->escape($this->state->get('list.ordering', 'a.language'));
$this->listDirn = $this->escape($this->state->get('list.direction', 'asc'));
$this->saveOrder = $this->listOrder == 'a.ordering';
// set the return here value
$this->return_here = urlencode(base64_encode((string) JUri::getInstance()));

View File

@ -47,8 +47,8 @@ class GetbibleViewVerses extends HtmlView
// Load the active filters.
$this->activeFilters = $this->get('ActiveFilters');
// Add the list ordering clause.
$this->listOrder = $this->escape($this->state->get('list.ordering', 'a.id'));
$this->listDirn = $this->escape($this->state->get('list.direction', 'DESC'));
$this->listOrder = $this->escape($this->state->get('list.ordering', 'g.translation'));
$this->listDirn = $this->escape($this->state->get('list.direction', 'asc'));
$this->saveOrder = $this->listOrder == 'a.ordering';
// set the return here value
$this->return_here = urlencode(base64_encode((string) JUri::getInstance()));

View File

@ -1,15 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<extension type="component" version="4" method="upgrade">
<name>COM_GETBIBLE</name>
<creationDate>1st August, 2023</creationDate>
<creationDate>2nd August, 2023</creationDate>
<author>Llewellyn van der Merwe</author>
<authorEmail>joomla@vdm.io</authorEmail>
<authorUrl>https://getbible.net</authorUrl>
<copyright>Copyright (C) 2015. All Rights Reserved</copyright>
<license>GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html</license>
<version>2.0.8</version>
<version>2.0.9</version>
<description><![CDATA[
<h1>Get Bible (v.2.0.8)</h1>
<h1>Get Bible (v.2.0.9)</h1>
<div style="clear: both;"></div>
<p>Welcome to the next level of scripture engagement - The Bible for Joomla! Our purpose is to bring the Word of God to every person, in their native language, entirely free. This isn't just a typical extension; it's a groundbreaking tool developed to span language divides and deliver a rich, customizable Bible study experience to users worldwide.

View File

@ -199,6 +199,33 @@ final class Linker
return false;
}
/**
* Check if the linker is authenticated
*
* @param string $linker The linker GUID value
*
* @return array Linker authenticated message
* @since 2.0.1
**/
public function authenticated(string $linker): array
{
if (($access = $this->session->get("getbible_active_{$linker}", null)) === null
|| $access !== 'valid_access')
{
return ['error' => Text::_('COM_GETBIBLE_SESSION_NOT_ACTIVE')];
}
// get current session
$current = $this->session->get('getbible_active_linker_guid', null);
if (strcasecmp($linker, $current) == 0)
{
return ['success' => Text::_('COM_GETBIBLE_SESSION_ACTIVE'), 'status' => true];
}
return ['success' => Text::_('COM_GETBIBLE_SESSION_ACTIVE'), 'status' => false];
}
/**
* The Share His Word Trigger
*

View File

@ -173,6 +173,7 @@ final class Tag
// update the description if it does not match
$description = $description ?? '';
$description = trim($description);
$_tag->description = $_tag->description ?? '';
if ($_tag->description !== $description && $this->update->value($description, 'description', $_tag->id, 'id', 'tag'))
{
$_tag->description = $description;
@ -237,13 +238,13 @@ final class Tag
* @param string $linker The linker GUID value
* @param string $name The tag name
*
* @return array|null Array of the tagged verse values on success
* @return object|null Array of the tagged verse values on success
* @since 2.0.1
**/
private function get(
string $linker,
string $name
): ?array
): ?object
{
// get tag if it exist
if (($tag = $this->load->item([

View File

@ -111,6 +111,32 @@ final class Chapter extends Watcher
return false;
}
/**
* Update translation book chapter names
*
* @param array $books The books ids.
*
* @return bool True on success
* @since 2.0.1
*/
public function names(array $books): bool
{
foreach ($books as $book)
{
if (($_book = $this->load->item(['id' => $book], 'book')) === null)
{
return false;
}
if (!$this->chapters($_book->abbreviation, $_book->nr))
{
return false;
}
}
return true;
}
/**
* Load the chapter numbers
*
@ -156,6 +182,80 @@ final class Chapter extends Watcher
return false;
}
/**
* Trigger the update of the chapters of a translation-book
*
* @param string $translation The translation.
* @param int $book The book number.
* @param bool $updateHash The switch to update the hash.
*
* @return bool True if update was a success
* @since 2.0.1
*/
private function chapters(string $translation, int $book, bool $updateHash = false): bool
{
// load all the verses from the local database
$inserted = false;
// get verses from the API
if (($api = $this->chapters->list($translation, $book)) === null)
{
return false;
}
if (($chapters = $this->load->items(
['abbreviation' => $translation, 'book_nr' => $book],
'chapter'
)) !== null)
{
$update = [];
$insert = [];
$match = ['key' => 'book_nr', 'value' => ''];
// dynamic update all verse objects
foreach ($api as $chapter)
{
// hash must only update/set if
// verses are also updated/set
if (!$updateHash)
{
unset($chapter->sha);
}
// check if the verse exist
$match['value'] = (string) $chapter->book_nr;
if (($object = $this->getTarget($match, $chapters)) !== null)
{
$chapter->id = $object->id;
$chapter->modified = $this->today;
$update[] = $chapter;
}
else
{
$insert[] = $chapter;
}
}
// check if we have values to insert
if ($insert !== [])
{
$inserted = $this->insert->items($insert, 'chapter');
}
// update the local chapters
if ($update !== [] && $this->update->items($update, 'id', 'chapter'))
{
return true;
}
}
else
{
$inserted = $this->insert->items((array) $api, 'chapter');
}
return $inserted;
}
/**
* Load verses
*
@ -208,16 +308,19 @@ final class Chapter extends Watcher
private function update(string $translation, int $book, int $chapter): bool
{
// load all the verses from the local database
$inserted = false;
// get verses from the API
if (($api = $this->verses->get($translation, $book, $chapter)) === null)
{
return false;
}
if (($verses = $this->load->items(
['abbreviation' => $translation, 'book_nr' => $book, 'chapter' => $chapter],
'verse'
)) !== null)
{
// get verses from the API
if (($api = $this->verses->get($translation, $book, $chapter)) === null)
{
return false;
}
$update = [];
$insert = [];
@ -228,7 +331,7 @@ final class Chapter extends Watcher
{
// check if the verse exist
$match['value'] = (string) $verse->verse;
if (($object = $this->getTarget($match, $verses)) !== null)
if ($verses !== null && ($object = $this->getTarget($match, $verses)) !== null)
{
$verse->id = $object->id;
$verse->modified = $this->today;
@ -243,7 +346,12 @@ final class Chapter extends Watcher
// check if we have values to insert
if ($insert !== [])
{
$this->insert->items($insert, 'verse');
$_insert = ['book_nr' => $book, 'abbreviation' => $translation];
array_walk($insert, function ($item, $key) use ($_insert) {
foreach ($_insert as $k => $v) { $item->$k = $v; }
});
$inserted = $this->insert->items($insert, 'verse');
}
// update the local verses
@ -252,8 +360,17 @@ final class Chapter extends Watcher
return true;
}
}
else
{
$insert = ['book_nr' => $book, 'abbreviation' => $translation];
array_walk($api->verses, function ($item, $key) use ($insert) {
foreach ($insert as $k => $v) { $item->$k = $v; }
});
return false;
$inserted = $this->insert->items((array) $api->verses, 'verse');
}
return $inserted;
}
/**

View File

@ -168,7 +168,7 @@ final class Translation extends Watcher
{
// check if the verse exist
$match['value'] = $translation->abbreviation ?? null;
if (($object = $this->getTarget($match, $local_translations)) !== null)
if ($local_translations !== null && ($object = $this->getTarget($match, $local_translations)) !== null)
{
$translation->id = $object->id;
$translation->created = $this->today;

View File

@ -1125,7 +1125,7 @@ class com_getbibleInstallerScript
{
$rule_length = $db->loadResult();
// Check the size of the rules column
if ($rule_length <= 43840)
if ($rule_length <= 44000)
{
// Fix the assets table rules column size
$fix_rules_size = "ALTER TABLE `#__assets` CHANGE `rules` `rules` TEXT NOT NULL COMMENT 'JSON encoded access control. Enlarged to TEXT by JCB';";
@ -1539,7 +1539,7 @@ class com_getbibleInstallerScript
echo '<a target="_blank" href="https://getbible.net" title="Get Bible">
<img src="components/com_getbible/assets/images/vdm-component.jpg"/>
</a>
<h3>Upgrade to Version 2.0.8 Was Successful! Let us know if anything is not working as expected.</h3>';
<h3>Upgrade to Version 2.0.9 Was Successful! Let us know if anything is not working as expected.</h3>';
// Set db if not set already.
if (!isset($db))

View File

@ -381,6 +381,20 @@ const setLinker = async (linker) => {
throw new Error(data); // throw an error if the request was not successful
}
};
/**
* JS Function check if a linker session is authenticated
*/
const isLinkerAuthenticated = async (linker) => {
// Make a request to your endpoint
const response = await fetch(getIsLinkerAuthenticatedURL(linker));
// Wait for the server to return the response, then parse it as JSON.
const data = await response.json();
if (data.success || data.error) {
return data; // return the data object on success
} else {
throw new Error(data); // throw an error if the request was not successful
}
};
/**
* JS Function to revoke linker session
*/
@ -678,31 +692,29 @@ const createTag = async (name, description) => {
const response = await fetch(getCreateTagURL(), options);
// Wait for the server to return the response, then parse it as JSON.
const data = await response.json();
// Call another function after the response has been received
if (data.success) {
if (data.access_required && data.error) {
setupGetBibleAccess(
'getbible-tag-creator',
data.error,
createTag,
[name, description]
);
} else if (data.success) {
// update the local object
setBibleTagItem(data.guid, data);
// Show success message
UIkit.notification({
message: data.success,
status: 'success',
timeout: 5000
});
} else if (data.access_required && data.error) {
setupGetBibleAccess(
'getbible-app-tags',
data.error,
setTag,
[name]
);
// close edit view open tag view
UIkit.modal('#getbible-tag-creator').hide();
UIkit.modal('#getbible-app-tags').show();
} else if (data.error) {
// Show danger message
UIkit.notification({
message: data.error,
status: 'danger',
timeout: 3000
});
} else {
// Handle any errors
console.error("Error occurred: ", data);
getbibleCreateTagError.style.display = '';
getbibleCreateTagErrorMessage.textContent = data.error;
}
} catch (error) {
// Handle any errors
@ -713,42 +725,61 @@ const createTag = async (name, description) => {
* JS Function to update a tag
*/
const updateTag = async (tag, name, description) => {
// build form
const formData = new FormData();
// add the form data
formData.set('tag', tag);
formData.set('name', name);
formData.set('description', description);
let options = {
method: 'POST',
body: formData
}
// Make a request to your endpoint
const response = await fetch(getUpdateTagURL(), options);
// Wait for the server to return the response, then parse it as JSON.
const data = await response.json();
if (data.access_required && data.error) {
setupGetBibleAccess(
'getbible-tag-editor',
data.error,
updateTag,
[tag, name, description]
);
} else if (data.success || data.error) {
return data; // return the data object on success
} else {
throw new Error(data); // throw an error if the request was not successful
try {
// build form
const formData = new FormData();
// add the form data
formData.set('tag', tag);
formData.set('name', name);
formData.set('description', description);
let options = {
method: 'POST',
body: formData
}
// Make a request to your endpoint
const response = await fetch(getUpdateTagURL(), options);
// Wait for the server to return the response, then parse it as JSON.
const data = await response.json();
if (data.access_required && data.error) {
setupGetBibleAccess(
'getbible-tag-editor',
data.error,
updateTag,
[tag, name, description]
);
} else if (data.success) {
// update the local object
setBibleTagItem(data.guid, data);
// Show success message
UIkit.notification({
message: data.success,
status: 'success',
timeout: 5000
});
// update the tags name if needed
setActiveVerse(getbibleEditTagRefeshVerse.value, false);
// close edit view open tag view
UIkit.modal('#getbible-tag-editor').hide();
UIkit.modal('#getbible-app-tags').show();
} else if (data.error) {
// Show danger message
getbibleEditTagError.style.display = '';
getbibleEditTagErrorMessage.textContent = data.error;
}
} catch (error) {
// Handle any errors
console.error("Error occurred: ", error);
}
};
/**
* JS Function to delete a tag
*/
const deleteTag = async (tag, name, description) => {
const deleteTag = async (tag) => {
try {
// build form
const formData = new FormData();
// add the form data
formData.set('guid', tag);
formData.set('tag', tag);
let options = {
method: 'POST',
body: formData
@ -757,31 +788,33 @@ const deleteTag = async (tag, name, description) => {
const response = await fetch(getDeleteTagURL(), options);
// Wait for the server to return the response, then parse it as JSON.
const data = await response.json();
// Call another function after the response has been received
if (data.success) {
if (data.access_required && data.error) {
setupGetBibleAccess(
'getbible-tag-editor',
data.error,
deleteTag,
[tag]
);
} else if (data.success) {
// Show success message
UIkit.notification({
message: data.success,
status: 'success',
timeout: 5000
});
} else if (data.access_required && data.error) {
setupGetBibleAccess(
'getbible-app-tags',
data.error,
setTag,
[name]
);
// update the local object
deleteBibleTagItem(getbibleEditTagGuid.value);
// update the tags name if needed
setActiveVerse(getbibleEditTagRefeshVerse.value, false);
// update the local and the html in the verses
// setInactiveTaggedVerse(getbibleEditTaggedGuid.value, getbibleEditTagRefeshVerse.value);
// close edit view open tag view
UIkit.modal('#getbible-tag-editor').hide();
UIkit.modal('#getbible-app-tags').show();
} else if (data.error) {
// Show danger message
UIkit.notification({
message: data.error,
status: 'danger',
timeout: 3000
});
} else {
// Handle any errors
console.error("Error occurred: ", data);
getbibleEditTagError.style.display = '';
getbibleEditTagErrorMessage.textContent = data.error;
}
} catch (error) {
// Handle any errors

View File

@ -38,6 +38,7 @@ class GetbibleControllerAjax extends BaseController
// load the tasks
$this->registerTask('getShareHisWordUrl', 'ajax');
$this->registerTask('checkValidLinker', 'ajax');
$this->registerTask('isLinkerAuthenticated', 'ajax');
$this->registerTask('installBibleChapter', 'ajax');
$this->registerTask('getAppUrl', 'ajax');
$this->registerTask('setLinker', 'ajax');
@ -161,6 +162,47 @@ class GetbibleControllerAjax extends BaseController
}
}
break;
case 'isLinkerAuthenticated':
try
{
$linkerValue = $jinput->get('linker', null, 'STRING');
if($linkerValue)
{
$result = $this->getModel('ajax')->isLinkerAuthenticated($linkerValue);
}
else
{
$result = false;
}
if($callback)
{
echo $callback . "(".json_encode($result).");";
}
elseif($returnRaw)
{
echo json_encode($result);
}
else
{
echo "(".json_encode($result).");";
}
}
catch(Exception $e)
{
if($callback)
{
echo $callback."(".json_encode($e).");";
}
elseif($returnRaw)
{
echo json_encode($e);
}
else
{
echo "(".json_encode($e).");";
}
}
break;
case 'installBibleChapter':
try
{

View File

@ -37,11 +37,14 @@ COM_GETBIBLE_CHAPTER="Chapter"
COM_GETBIBLE_CHAPTERS="Chapters"
COM_GETBIBLE_COMPLETION_TOKENS="Completion Tokens"
COM_GETBIBLE_COPY="Copy"
COM_GETBIBLE_CREATE="Create"
COM_GETBIBLE_CREATED="Created"
COM_GETBIBLE_CREATE_NEW_S="Create New %s"
COM_GETBIBLE_CREATE_TAG="Create Tag"
COM_GETBIBLE_DAILY_VERSE="Daily Verse"
COM_GETBIBLE_DEACTIVATE_THIS_INSTALLATION_OPTION="Deactivate this Installation Option"
COM_GETBIBLE_DEBUG="Debug"
COM_GETBIBLE_DELETE="Delete"
COM_GETBIBLE_DESCRIPTION="Description"
COM_GETBIBLE_DETAILS="Details"
COM_GETBIBLE_DIRECTION="Direction"
@ -149,9 +152,11 @@ COM_GETBIBLE_SEARCH_RESULTS="Search Results"
COM_GETBIBLE_SELECT="Select"
COM_GETBIBLE_SENSITIVE="Sensitive"
COM_GETBIBLE_SESSIONS="Sessions"
COM_GETBIBLE_SESSION_ACTIVE="Session active."
COM_GETBIBLE_SESSION_KEY="Session Key"
COM_GETBIBLE_SESSION_KEY_COULD_NOT_BE_STORED="Session key could not be stored."
COM_GETBIBLE_SESSION_NAME="Session Name"
COM_GETBIBLE_SESSION_NOT_ACTIVE="Session not active."
COM_GETBIBLE_SETTINGS="Settings"
COM_GETBIBLE_SHARE="Share"
COM_GETBIBLE_SHARE_LINK="Share Link"
@ -171,7 +176,9 @@ COM_GETBIBLE_TAGGING_THIS_VERSE="Tagging this verse."
COM_GETBIBLE_TAGS="Tags"
COM_GETBIBLE_TAG_ALREADY_EXIST_BUT_COULD_NOT_BE_REACTIVATED="Tag already exist, but could not be reactivated."
COM_GETBIBLE_TAG_DESC="getBible Tag"
COM_GETBIBLE_TAG_DESCRIPTION="Tag Description"
COM_GETBIBLE_TAG_FOUND_BUT_COULD_NOT_BE_REACTIVATED="Tag found, but could not be reactivated."
COM_GETBIBLE_TAG_NAME="Tag Name"
COM_GETBIBLE_TAG_SUCCESSFULLY_DELETED="Tag successfully deleted."
COM_GETBIBLE_TARGETED_BOOKS="Targeted Books"
COM_GETBIBLE_TEMPERATURE="Temperature"
@ -237,10 +244,12 @@ COM_GETBIBLE_YOUR_SEARCH_DIDNT_YIELD_ANY_RESULTS_PLEASE_TYPE_A_DIFFERENT_KEYWORD
COM_GETBIBLE_YOU_ARE_ABOUT_TO_INITIATE_THE_INSTALLATION_PROCESS_FOR_THIS_TRANSLATION_PLEASE_NOTE_THIS_PROCEDURE_IS_QUITE_EXTENSIVE_AND_MAY_TAKE_A_SIGNIFICANT_AMOUNT_OF_TIME_TO_COMPLETE_DEPENDING_ON_YOUR_NETWORK_SPEED_IT_COULD_RANGE_FROM_SEVERAL_MINUTES_TO_A_FEW_HOURS_DURING_THIS_PERIOD_IT_IS_ESSENTIAL_THAT_YOU_DO_NOT_NAVIGATE_AWAY_FROM_THIS_PAGE_CLOSE_THE_BROWSER_OR_SHUT_DOWN_YOUR_COMPUTER_AS_THIS_COULD_INTERRUPT_THE_INSTALLATION_PROCESS_PLEASE_ENSURE_YOU_HAVE_A_STABLE_INTERNET_CONNECTION_AND_SUFFICIENT_TIME_BEFORE_PROCEEDING_WE_RECOMMEND_INITIATING_THIS_WHEN_YOU_DO_NOT_REQUIRE_IMMEDIATE_USE_OF_YOUR_DEVICE_ARE_YOU_SURE_YOU_WANT_TO_START_THE_INSTALLATION_NOW="You are about to initiate the installation process for this translation. Please note, this procedure is quite extensive and may take a significant amount of time to complete, depending on your network speed. It could range from several minutes to a few hours. During this period, it is essential that you do not navigate away from this page, close the browser or shut down your computer as this could interrupt the installation process. Please ensure you have a stable internet connection and sufficient time before proceeding. We recommend initiating this when you do not require immediate use of your device. Are you sure you want to start the installation now?"
COM_GETBIBLE_YOU_ARE_ABOUT_TO_LOAD_ANOTHER_PERSISTENT_SESSION_KEY_ARE_YOU_SURE_YOU_WOULD_LIKE_TO_CONTINUE="You are about to load another persistent session key, are you sure you would like to continue?"
COM_GETBIBLE_YOU_ARE_ABOUT_TO_REMOVE_THE_ACTIVE_PERSISTENT_SESSION="You are about to remove the active persistent session."
COM_GETBIBLE_YOU_ARE_ABOUT_TO_REMOVE_THIS_TAG_ENTIRELY_THIS_PROCESS_WILL_ALSO_DISCONNECT_THIS_TAG_FROM_ALL_VERSES_MEANING_THAT_IT_WILL_NO_LONGER_EXIST_IN_ANY_CONTEXT="You are about to remove this tag entirely. This process will also disconnect this tag from all verses, meaning that it will no longer exist in any context."
COM_GETBIBLE_YOU_CAN_ADD_IT_HERE_TO_LOAD_YOUR_PREVIOUS_SESSION="You can add it here to load your previous session."
COM_GETBIBLE_YOU_CAN_CHANGE_YOUR_SESSION_NAME_TO_SOMETHING_MORE_RECOGNIZABLE="You can change your session name to something more recognizable."
COM_GETBIBLE_YOU_CAN_SHARE_YOUR_SESSION_WITH_LOVED_ONES_SO_THEY_CAN_SEE_YOUR_NOTES_AND_TAGS="You can share your session with loved ones so they can see your notes and tags."
COM_GETBIBLE_YOU_HAVE_ENTERED_A_VALID_SESSION_KEY="You have entered a valid session key."
COM_GETBIBLE_YOU_MUST_ADD_A_TAG_NAME="You must add a tag name."
COM_GETBIBLE_YOU_SHOULD_SELECT_ONE_OF_BYOUR_FAVOURITEB_VERSES="You should select one of <b>your favourite</b> verses."
JGLOBAL_FIELD_ID_DESC="Record number in the database."
JGLOBAL_FIELD_ID_LABEL="ID"

View File

@ -180,6 +180,24 @@ class GetbibleModelAjax extends ListModel
return ['error' => JText::_('COM_GETBIBLE_THERE_HAS_BEEN_AN_ERROR_PLEASE_TRY_AGAIN')];
}
/**
* Is the Linker Authenticated
*
* @param string $linker The linker GUID value
*
* @return array
* @since 3.2.0
**/
public function isLinkerAuthenticated(string $linker): array
{
if (($authenticated = Factory::_('GetBible.Linker')->authenticated(trim($linker))) !== null)
{
return $authenticated;
}
return ['error' => JText::_('COM_GETBIBLE_THERE_HAS_BEEN_AN_ERROR_PLEASE_TRY_AGAIN')];
}
/**
* Set the Linker access
*

View File

@ -119,20 +119,6 @@ class GetbibleModelTag extends ListModel
{
return false;
}
// Check if $this->translation is a string or numeric value.
$checkValue = $this->translation;
if (isset($checkValue) && GetbibleHelper::checkString($checkValue))
{
$query->where('b.abbreviation = ' . $db->quote($checkValue));
}
elseif (is_numeric($checkValue))
{
$query->where('b.abbreviation = ' . $checkValue);
}
else
{
return false;
}
// Get where a.published is 1
$query->where('a.published = 1');
// Get where a.access is 1
@ -147,6 +133,8 @@ class GetbibleModelTag extends ListModel
$query->where('v.chapter = a.chapter');
// Get where v.verse is a.verse
$query->where('v.verse = a.verse');
// Get where b.abbreviation is v.abbreviation
$query->where('b.abbreviation = v.abbreviation');
$query->order('a.book_nr ASC');
$query->order('a.chapter ASC');
$query->order('a.verse ASC');
@ -626,9 +614,6 @@ class GetbibleModelTag extends ListModel
$query->where('v.chapter = a.chapter');
// Get where v.verse is a.verse
$query->where('v.verse = a.verse');
$query->order('a.book_nr ASC');
$query->order('a.chapter ASC');
$query->order('a.verse ASC');
// Reset the query using our newly populated query object.
$db->setQuery($query);

View File

@ -56,7 +56,7 @@ var triggerGetBibleReload = false;
// function to access verses by number
const getActiveVerseText = (verseNumber) => {
const verseObj = getbible_verses.find(verse => verse.verse === verseNumber.toString());
return verseObj ? verseObj.text : "oops... there was an error! verse not found";
return verseObj ? verseObj.text : '';
}
<?php if ($this->params->get('activate_sharing') == 1 || $this->params->get('activate_tags') == 1 || $this->params->get('activate_notes') == 1): ?>
<?php if ($this->notes): ?>
@ -184,6 +184,16 @@ const setBibleTagItem = (guid, tagItem) => {
getbible_tags.push(tagItem);
}
};
const deleteBibleTagItem = (guid) => {
let index = getbible_tags.findIndex(item => item.guid == guid);
if (index !== -1) {
// If the item exists, remove it
getbible_tags.splice(index, 1);
} else {
// If the item doesn't exist, do nothing
console.log('Item does not exist');
}
};
const setActiveTaggedVerse = async (data) => {
let found = false;
getbible_tagged.forEach((itemData) => {
@ -251,6 +261,20 @@ const getbibleActiveVerse = {
for (let i = 0; i < getbibleVerseSelectedText.length; i++) {
getbibleVerseSelectedText[i].textContent = verseText;
}
// Update all elements with the class name `getbible-verse-pre-text`
let getbibleVersePreText = document.getElementsByClassName('getbible-verse-pre-text');
let pre_value = val - 1;
let versePre = getActiveVerseText(pre_value);
for (let i = 0; i < getbibleVersePreText.length; i++) {
getbibleVersePreText[i].textContent = versePre;
}
// Update all elements with the class name `getbible-verse-post-text`
let getbibleVersePostText = document.getElementsByClassName('getbible-verse-post-text');
let post_value = val + 1;
let versePost = getActiveVerseText(post_value);
for (let i = 0; i < getbibleVersePostText.length; i++) {
getbibleVersePostText[i].textContent = versePost;
}
<?php if ($this->params->get('activate_notes') == 1): ?> // update the note
setActiveNoteTextarea(this._value);<?php endif; ?>
<?php if ($this->params->get('activate_tags') == 1): ?> // update the tags

View File

@ -30,8 +30,12 @@ defined('_JEXEC') or die('Restricted access');
<div id="verse-note-selection-slider"></div>
</div>
<div class="uk-margin">
<p class="uk-text-muted uk-text-small uk-margin-remove getbible-verse-pre-text direction-<?php echo strtolower($this->translation->direction); ?>"
dir="<?php echo $this->translation->direction; ?>"></p>
<p class="uk-text-emphasis uk-margin-remove getbible-verse-selected-text direction-<?php echo strtolower($this->translation->direction); ?>"
dir="<?php echo $this->translation->direction; ?>"><?php echo JText::_('COM_GETBIBLE_THE_ACTIVE_VERSE_SELECTED_TEXT_SHOULD_LOAD_HERE'); ?></p>
<p class="uk-text-muted uk-text-small uk-margin-remove getbible-verse-post-text direction-<?php echo strtolower($this->translation->direction); ?>"
dir="<?php echo $this->translation->direction; ?>"></p>
<textarea id="verse-note-textarea" class="uk-textarea uk-margin" rows="5" placeholder="<?php echo JText::_('COM_GETBIBLE_ADD_YOUR_NOTES_HERE'); ?>" aria-label="Textarea"></textarea>
<button id="save-verse-note" class="uk-button uk-width-1-1 uk-button-default" onclick="saveGetBibleNote();"><?php echo JText::_('COM_GETBIBLE_SAVE'); ?></button>
</div>

View File

@ -341,9 +341,9 @@ function setSharedValues(start, end, update = true) {
var trans_ref = '';
if (tmp["getbible-translation-share"] === "2") {
trans_ref = ' (<?php echo $this->chapter->abbreviation; ?>)';
trans_ref = ' (' + <?php echo json_encode($this->chapter->abbreviation); ?> + ')';
} else if (tmp["getbible-translation-share"] === "3") {
trans_ref = ' <?php echo $this->chapter->translation; ?>';
trans_ref = ' ' + <?php echo json_encode($this->chapter->translation); ?>;
}
var breaking_val = ' ';
@ -358,7 +358,7 @@ function setSharedValues(start, end, update = true) {
var name_ref = '';
if (tmp["getbible-reference-share"] === "2" ||
tmp["getbible-reference-share"] === "3") {
name_ref = '<?php echo $this->chapter->name; ?>:' + verse_ref + trans_ref;
name_ref = <?php echo json_encode($this->chapter->name); ?> + ':' + verse_ref + trans_ref;
if (tmp["getbible-link-share"] === "1") {
if (tmp["getbible-format-share"] === "3") {
name_ref = '<a href="' + share_url + '">' + name_ref + '</a>';

View File

@ -18,15 +18,25 @@
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
$content = '<div class="uk-alert-success" id="getbible-edit-tag-error" uk-alert style="display:none"><p id="getbible-edit-tag-error-message"></p></div>';
$content .= JLayoutHelper::render('inputbox', ['id' => 'getbible-edit-tag-name', 'label' => JText::_('COM_GETBIBLE_NAME')]);
$content .= JLayoutHelper::render('textareabox', ['id' => 'getbible-edit-tag-description', 'label' => JText::_('COM_GETBIBLE_DESCRIPTION')]);
$content .= '<input id="getbible-edit-tag-guid" type="hidden">';
$content .= '<input id="getbible-edit-tag-verse" type="hidden">';
$edit_content = '<div class="uk-alert-success" id="getbible-edit-tag-error" uk-alert style="display:none"><p id="getbible-edit-tag-error-message"></p></div>';
$edit_content .= JLayoutHelper::render('inputbox', ['id' => 'getbible-edit-tag-name', 'label' => JText::_('COM_GETBIBLE_NAME')]);
$edit_content .= JLayoutHelper::render('textareabox', ['id' => 'getbible-edit-tag-description', 'label' => JText::_('COM_GETBIBLE_DESCRIPTION')]);
$edit_content .= '<input id="getbible-edit-tag-guid" type="hidden">';
$edit_content .= '<input id="getbible-edit-tag-verse" type="hidden">';
// set buttons
$buttons = [
['id' => 'getbible-save-edit-tag', 'name' => JText::_('COM_GETBIBLE_SAVE'), 'class' => 'uk-button uk-button-default uk-width-2-3'],
['id' => 'getbible-cancel-edit-tag', 'name' => JText::_('COM_GETBIBLE_CANCEL'), 'class' => 'uk-button uk-button-danger uk-width-1-3']
$edit_buttons = [
['id' => 'getbible-save-edit-tag', 'name' => JText::_('COM_GETBIBLE_SAVE'), 'class' => 'uk-button uk-button-primary uk-width-2-4'],
['id' => 'getbible-delete-edit-tag', 'name' => JText::_('COM_GETBIBLE_DELETE'), 'class' => 'uk-button uk-button-danger uk-width-1-4'],
['id' => 'getbible-cancel-edit-tag', 'name' => JText::_('COM_GETBIBLE_CANCEL'), 'class' => 'uk-button uk-button-default uk-width-1-4']
];
$create_content = '<div class="uk-alert-success" id="getbible-create-tag-error" uk-alert style="display:none"><p id="getbible-create-tag-error-message"></p></div>';
$create_content .= JLayoutHelper::render('inputbox', ['id' => 'getbible-create-tag-name', 'label' => JText::_('COM_GETBIBLE_NAME'), 'placeholder' => JText::_('COM_GETBIBLE_TAG_NAME')]);
$create_content .= JLayoutHelper::render('textareabox', ['id' => 'getbible-create-tag-description', 'label' => JText::_('COM_GETBIBLE_DESCRIPTION'), 'placeholder' => JText::_('COM_GETBIBLE_TAG_DESCRIPTION')]);
// set buttons
$create_buttons = [
['id' => 'getbible-create-tag', 'name' => JText::_('COM_GETBIBLE_CREATE'), 'class' => 'uk-button uk-button-primary uk-width-2-3'],
['id' => 'getbible-cancel-create-tag', 'name' => JText::_('COM_GETBIBLE_CANCEL'), 'class' => 'uk-button uk-button-default uk-width-1-3']
];
?>
@ -41,19 +51,21 @@ $buttons = [
<div id="verse-tag-selection-slider"></div>
</div>
<div class="uk-margin">
<p class="uk-text-emphasis uk-margin-remove-top getbible-verse-selected-text direction-<?php echo strtolower($this->translation->direction); ?>"
<p class="uk-text-muted uk-text-small uk-margin-remove getbible-verse-pre-text direction-<?php echo strtolower($this->translation->direction); ?>"
dir="<?php echo $this->translation->direction; ?>"></p>
<p class="uk-text-emphasis uk-margin-remove getbible-verse-selected-text direction-<?php echo strtolower($this->translation->direction); ?>"
dir="<?php echo $this->translation->direction; ?>"><?php echo JText::_('COM_GETBIBLE_THE_ACTIVE_VERSE_SELECTED_TEXT_SHOULD_LOAD_HERE'); ?></p>
<p class="uk-text-muted uk-text-small uk-margin-remove getbible-verse-post-text direction-<?php echo strtolower($this->translation->direction); ?>"
dir="<?php echo $this->translation->direction; ?>"></p>
<div class="uk-child-width-1-2@s uk-grid-small" uk-grid>
<div>
<div style="position: sticky; top: 0;">
<h4><?php echo JText::_('COM_GETBIBLE_ACTIVE'); ?></h4>
<div id="getbible-active-tags" uk-sortable="group: getbible-tag-selection, handle: .uk-sortable-handle">
<!-- Active items will be dynamically added here -->
</div>
<h4><?php echo JText::_('COM_GETBIBLE_ACTIVE'); ?></h4>
<div id="getbible-active-tags" uk-sortable="group: getbible-tag-selection, handle: .uk-sortable-handle" style="max-height: 400px; overflow-y: auto;">
<!-- Active items will be dynamically added here -->
</div>
</div>
<div>
<h4><?php echo JText::_('COM_GETBIBLE_AVAILABLE_TAGS'); ?></h4>
<h4><?php echo JText::_('COM_GETBIBLE_AVAILABLE_TAGS'); ?> <a id="getbible-create-new-tag" href="#" uk-icon="plus" uk-tooltip="title: <?php echo JText::_('COM_GETBIBLE_CREATE_TAG'); ?>"></a></h4>
<div id="getbible-tags" class="uk-width-auto uk-grid-small" uk-sortable="group: getbible-tag-selection, handle: .uk-sortable-handle" style="max-height: 400px; overflow-y: auto;" uk-grid>
<!-- All items will be dynamically added here -->
</div>
@ -81,15 +93,32 @@ $buttons = [
'header' => JText::_('COM_GETBIBLE_EDIT_TAG'),
'header_class_other' => 'uk-text-center',
'close' => true,
'content' => $content,
'content' => $edit_content,
'buttons_class' => 'uk-button-group uk-width-1-1',
'buttons_id' => 'getbible-tag-edit-buttons',
'buttons' => $buttons
'buttons' => $edit_buttons
]); ?>
<?php echo JLayoutHelper::render('modal', [
'id' => 'getbible-tag-creator',
'header' => JText::_('COM_GETBIBLE_CREATE_TAG'),
'header_class_other' => 'uk-text-center',
'close' => true,
'content' => $create_content,
'buttons_class' => 'uk-button-group uk-width-1-1',
'buttons_id' => 'getbible-tag-create-buttons',
'buttons' => $create_buttons
]); ?>
<script type="text/javascript">
// track the scroller of the tags
new ScrollMemory('getbible-tags');
// set the edit module handles
const getbibleCreateNewTag = document.getElementById('getbible-create-new-tag');
const getbibleCreateTagError = document.getElementById('getbible-create-tag-error');
const getbibleCreateTagErrorMessage = document.getElementById('getbible-create-tag-error-message');
const getbibleCreateTagName= document.getElementById('getbible-create-tag-name');
const getbibleCreateTagDescription = document.getElementById('getbible-create-tag-description');
const getbibleCreateTag = document.getElementById('getbible-create-tag');
const getbibleCanselCreateTag = document.getElementById('getbible-cancel-create-tag');
const getbibleEditTagError = document.getElementById('getbible-edit-tag-error');
const getbibleEditTagErrorMessage = document.getElementById('getbible-edit-tag-error-message');
const getbibleEditTagName= document.getElementById('getbible-edit-tag-name');
@ -97,36 +126,64 @@ const getbibleEditTagDescription = document.getElementById('getbible-edit-tag-de
const getbibleEditTagGuid = document.getElementById('getbible-edit-tag-guid');
const getbibleEditTagRefeshVerse = document.getElementById('getbible-edit-tag-verse');
const getbibleSaveEditTag = document.getElementById('getbible-save-edit-tag');
const getbibleDeleteEditTag = document.getElementById('getbible-delete-edit-tag');
const getbibleCanselEditTag = document.getElementById('getbible-cancel-edit-tag');
// update tag button click events
getbibleSaveEditTag.onclick = async function () {
getbibleCreateNewTag.onclick = async function () {
try {
getbibleEditTagError.style.display = 'none';
// trigger update of tag
let data = await updateTag(getbibleEditTagGuid.value, getbibleEditTagName.value, getbibleEditTagDescription.value);
if (data.success) {
// update the local object
setBibleTagItem(data.guid, data);
// Show success message
UIkit.notification({
message: data.success,
status: 'success',
timeout: 5000
});
// update the tags name if needed
setActiveVerse(getbibleEditTagRefeshVerse.value, false);
// close edit view open tag view
UIkit.modal('#getbible-tag-editor').hide();
UIkit.modal('#getbible-app-tags').show();
} else if (data.error) {
// Show danger message
getbibleEditTagError.style.display = '';
getbibleEditTagErrorMessage.textContent = data.error;
getbibleCreateTagError.style.display = 'none';
// hide the tags modal
UIkit.modal('#getbible-app-tags').hide();
// add the values to the fields
getbibleCreateTagName.value = '';
getbibleCreateTagDescription.value = '';
// show the edit tag modal
UIkit.modal('#getbible-tag-creator').show();
} catch (error) {
console.error("Error occurred: ", error);
}
}
getbibleCreateTag.onclick = async function () {
try {
if (getbibleCreateTagName.value.length == 0) {
getbibleCreateTagError.style.display = '';
getbibleCreateTagErrorMessage.textContent = '<?php echo JText::_('COM_GETBIBLE_YOU_MUST_ADD_A_TAG_NAME'); ?>';
} else {
getbibleCreateTagError.style.display = 'none';
// trigger create of tag
createTag(getbibleCreateTagName.value, getbibleCreateTagDescription.value);
}
} catch (error) {
console.error("Error occurred: ", error);
}
}
getbibleCanselCreateTag.onclick = async function () {
try {
// close edit view open tag view
UIkit.modal('#getbible-tag-creator').hide();
UIkit.modal('#getbible-app-tags').show();
} catch (error) {
console.error("Error occurred: ", error);
}
}
getbibleSaveEditTag.onclick = async function () {
try {
getbibleEditTagError.style.display = 'none';
// trigger update of tag
updateTag(getbibleEditTagGuid.value, getbibleEditTagName.value, getbibleEditTagDescription.value);
} catch (error) {
console.error("Error occurred: ", error);
}
}
getbibleDeleteEditTag.onclick = async function () {
getbibleEditTagError.style.display = 'none';
// trigger update of tag
UIkit.modal.confirm('<?php echo JText::_('COM_GETBIBLE_YOU_ARE_ABOUT_TO_REMOVE_THIS_TAG_ENTIRELY_THIS_PROCESS_WILL_ALSO_DISCONNECT_THIS_TAG_FROM_ALL_VERSES_MEANING_THAT_IT_WILL_NO_LONGER_EXIST_IN_ANY_CONTEXT'); ?>').then( async function() {
deleteTag(getbibleEditTagGuid.value);
}, function () {
console.log('Deleting of the tag cancelled.')
});
}
getbibleCanselEditTag.onclick = async function () {
try {
// close edit view open tag view

View File

@ -199,8 +199,8 @@ const setSessionStatusAccess = async () => {
// check if we have an open or closed session
let linker = getLocalMemory('getbible_active_linker_guid');
if (linker) {
let pass = getLocalMemory(linker + '-validated');
if (pass) {
let access = await isLinkerAuthenticated(linker);
if (access.success && access.status) {
unlockSessionStatusAccess();
} else {
lockSessionStatusAccess();

View File

@ -712,6 +712,11 @@ class GetbibleViewApp extends HtmlView
return UrlAjax +
'setLinker&linker=' + linker;
};
const getIsLinkerAuthenticatedURL = (linker) => {
// build is linker authenticated url
return UrlAjax +
'isLinkerAuthenticated&linker=' + linker;
};
const revokeLinkerSessionURL = () => {
// build set linker revoke access url
return UrlAjax + 'revokeLinkerSession';

View File

@ -132,6 +132,9 @@ class GetbibleViewTag extends HtmlView
// update the notes array if we have values
if ($mergeTags !== [])
{
usort($mergeTags, function($a, $b) {
return strcmp($a->name, $b->name);
});
// Reset the keys to be numeric and start from 0
$this->tags = array_values($mergeTags);
}

View File

@ -143,4 +143,22 @@
<maintainerurl>https://getbible.net</maintainerurl>
<targetplatform name="joomla" version="3.*"/>
</update>
<update>
<name>Get Bible</name>
<description>The Bible for Joomla</description>
<element>pkg_getbible</element>
<type>package</type>
<client>site</client>
<version>2.0.9</version>
<infourl title="Get Bible!">https://getbible.net</infourl>
<downloads>
<downloadurl type="full" format="zip">https://git.vdm.dev/api/v1/repos/getBible/joomla-pkg/archive/v2.0.9.zip</downloadurl>
</downloads>
<tags>
<tag>stable</tag>
</tags>
<maintainer>Llewellyn van der Merwe</maintainer>
<maintainerurl>https://getbible.net</maintainerurl>
<targetplatform name="joomla" version="3.*"/>
</update>
</updates>