diff --git a/composer.json b/composer.json index 4e681987f..8f432ab70 100644 --- a/composer.json +++ b/composer.json @@ -34,7 +34,7 @@ "require-dev": { "fzaninotto/faker": "~1.4", "phpunit/phpunit": "~4.0", - "phpunit/phpunit-selenium": ">=1.2" + "phpunit/phpunit-selenium": "~1.2" }, "autoload-dev": { "classmap": [ diff --git a/modules/backend/behaviors/RelationController.php b/modules/backend/behaviors/RelationController.php index 537e01983..028452e85 100644 --- a/modules/backend/behaviors/RelationController.php +++ b/modules/backend/behaviors/RelationController.php @@ -613,8 +613,6 @@ class RelationController extends ControllerBehavior $this->relationObject->addConstraints(); } - $this->controller->relationExtendQuery($query, $this->field); - /* * Allows pivot data to enter the fray */ @@ -765,8 +763,6 @@ class RelationController extends ControllerBehavior if (count($existingIds)) { $query->whereNotIn($this->relationModel->getQualifiedKeyName(), $existingIds); } - - $this->controller->relationExtendQuery($query, $this->field); }); } @@ -1204,20 +1200,6 @@ class RelationController extends ControllerBehavior // Overrides // - /** - * !!!! - * !!!! WARNING: DO NOT USE - This method is scheduled to be removed - * !!!! - * - * Controller override: Extend the query used for populating the list - * after the default query is processed. - * @param October\Rain\Database\Builder $query - * @param string $field - */ - public function relationExtendQuery($query, $field) - { - } - /** * Provides an opportunity to manipulate the view widget. * @param Backend\Classes\WidgetBase $widget diff --git a/modules/backend/widgets/Table.php b/modules/backend/widgets/Table.php index 0eea00410..aa882cdba 100644 --- a/modules/backend/widgets/Table.php +++ b/modules/backend/widgets/Table.php @@ -198,6 +198,41 @@ class Table extends WidgetBase ]; } + public function onServerCreateRecord() + { + if ($this->isClientDataSource()) { + throw new SystemException('The Table widget is not configured to use the server data source.'); + } + + $this->dataSource->createRecord( + post('recordData'), + post('placement'), + post('relativeToKey') + ); + + return $this->onServerGetRecords(); + } + + public function onServerUpdateRecord() + { + if ($this->isClientDataSource()) { + throw new SystemException('The Table widget is not configured to use the server data source.'); + } + + $this->dataSource->updateRecord(post('key'), post('recordData')); + } + + public function onServerDeleteRecord() + { + if ($this->isClientDataSource()) { + throw new SystemException('The Table widget is not configured to use the server data source.'); + } + + $this->dataSource->deleteRecord(post('key')); + + return $this->onServerGetRecords(); + } + public function onGetDropdownOptions() { $columnName = Input::get('column'); diff --git a/modules/backend/widgets/table/README.md b/modules/backend/widgets/table/README.md index 403ead01b..d823aa4ea 100644 --- a/modules/backend/widgets/table/README.md +++ b/modules/backend/widgets/table/README.md @@ -106,7 +106,7 @@ The client memory data sources keeps the data in the client memory. The data is ### Server memory data source ($.oc.table.datasource.server) -**TODO:** document this +**TODO:** document this ## Cell processors ($.oc.table.processor) @@ -137,7 +137,7 @@ The drop-down column type can load options from the column configuration or with blue: Blue width: 15% -If the `options` element is not presented in the configuration, the options will be loaded with AJAX. +If the `options` element is not presented in the configuration, the options will be loaded with AJAX. **TODO:** Document the AJAX interface @@ -203,7 +203,7 @@ Columns are defined as array with the `columns` property. The array keys corresp - `title` - `type` (string, checkbox, dropdown, autocomplete) - `width` - sets the column width, can be specified in percents (10%) or pixels (50px). There could be a single column without width specified, it will be stretched to take the available space. -- `readOnly` +- `readOnly` - prevents the cell value from being modified. Default: false. - `options` (for drop-down elements and autocomplete types) - `dependsOn` (from drop-down elements) - validation - defines the column client-side validation rules. See the **Client-side validation** section below. @@ -212,7 +212,7 @@ Columns are defined as array with the `columns` property. The array keys corresp ### table.getDropdownOptions -table.getDropdownOptions - triggered when drop-down options are requested by the client. Parameters: +table.getDropdownOptions - triggered when drop-down options are requested by the client. Parameters: - `$columnName` - specifies the drop-down column name. - `$rowData` - an array containing values of all columns in the table row. @@ -220,7 +220,7 @@ table.getDropdownOptions - triggered when drop-down options are requested by the Example event handler: ``` -$table->bindEvent('table.getDropdownOptions', +$table->bindEvent('table.getDropdownOptions', function ($columnName, $rowData) { if ($columnName == 'state') return ['ca'=>'California', 'wa'=>'Washington']; diff --git a/modules/backend/widgets/table/ServerEventDataSource.php b/modules/backend/widgets/table/ServerEventDataSource.php index 1c4325f9f..91862cbd5 100644 --- a/modules/backend/widgets/table/ServerEventDataSource.php +++ b/modules/backend/widgets/table/ServerEventDataSource.php @@ -11,7 +11,7 @@ class ServerEventDataSource extends DataSourceBase * Return records from the data source. * @param integer $offset Specifies the offset of the first record to return, zero-based. * @param integer $count Specifies the number of records to return. - * @return array Returns the records. + * @return array Returns the records. * If there are no more records, returns an empty array. */ public function getRecords($offset, $count) @@ -28,6 +28,33 @@ class ServerEventDataSource extends DataSourceBase return $this->fireEvent('data.getCount', [], true); } + /** + * Updates a record in the data source. + * @return void + */ + public function createRecord($data, $placement, $relativeToKey) + { + return $this->fireEvent('data.createRecord', [$data, $placement, $relativeToKey]); + } + + /** + * Updates a record in the data source. + * @return void + */ + public function updateRecord($key, $data) + { + $this->fireEvent('data.updateRecord', [$key, $data]); + } + + /** + * Removes a record from the data source. + * @return array Returns the remaining records. + */ + public function deleteRecord($key) + { + return $this->fireEvent('data.deleteRecord', [$key], true); + } + /** * Initializes records in the data source. * The method doesn't replace existing records and diff --git a/modules/backend/widgets/table/assets/js/build-min.js b/modules/backend/widgets/table/assets/js/build-min.js index c76219001..0485ca775 100644 --- a/modules/backend/widgets/table/assets/js/build-min.js +++ b/modules/backend/widgets/table/assets/js/build-min.js @@ -85,7 +85,8 @@ if(this.options.adding){var addBelowButton=document.createElement('a') addBelowButton.setAttribute('class','btn table-icon add-table-row-below') addBelowButton.setAttribute('data-cmd','record-add-below') this.toolbar.appendChild(addBelowButton) -if(this.navigation.paginationEnabled()||!this.options.rowSorting){addBelowButton.textContent=this.options.btnAddRowLabel}else{addBelowButton.textContent=this.options.btnAddRowBelowLabel +if(this.navigation.paginationEnabled()||!this.options.rowSorting){addBelowButton.textContent=this.options.btnAddRowLabel} +else{addBelowButton.textContent=this.options.btnAddRowBelowLabel var addAboveButton=document.createElement('a') addAboveButton.setAttribute('class','btn table-icon add-table-row-above') addAboveButton.textContent='Add row above' @@ -124,6 +125,7 @@ if(onSuccess) onSuccess() if(totalCount==0) self.addRecord('above',true) +self.$el.trigger('oc.tableUpdateData',[records,totalCount]) self=null})} Table.prototype.updateColumnWidth=function(){var headerCells=this.headerTable.querySelectorAll('th'),dataCells=this.dataTable.querySelectorAll('tr:first-child td') for(var i=0,len=headerCells.length;i0){var self=this this.gotoPage(this.pageIndex-1,function navUpPageSuccess(){self.focusCell('bottom',cellIndex) @@ -502,8 +505,7 @@ if(!isTab&&this.tableObj.activeCellProcessor&&!this.tableObj.activeCellProcessor return var row=this.tableObj.activeCell.parentNode,newIndex=(!ev.shiftKey||isTab)?this.tableObj.activeCell.cellIndex-1:0 var cell=row.children[newIndex] -if(cell) -this.tableObj.focusCell(cell) +if(cell){this.tableObj.focusCell(cell)} else{this.navigateUp(ev,row.children.length-1,isTab)}} Navigation.prototype.navigateRight=function(ev,isTab){if(!this.tableObj.activeCell) return @@ -511,8 +513,7 @@ if(!isTab&&this.tableObj.activeCellProcessor&&!this.tableObj.activeCellProcessor return var row=this.tableObj.activeCell.parentNode,newIndex=!ev.shiftKey?this.tableObj.activeCell.cellIndex+1:row.children.length-1 var cell=row.children[newIndex] -if(cell) -this.tableObj.focusCell(cell) +if(cell){this.tableObj.focusCell(cell)} else{this.navigateDown(ev,0)}} Navigation.prototype.navigateNext=function(ev){if(!this.tableObj.activeCell) return @@ -524,8 +525,7 @@ else this.navigateLeft(ev,true) this.tableObj.stopEvent(ev)} Navigation.prototype.focusCell=function(rowReference,cellIndex){var row=null,tbody=this.tableObj.getDataTableBody() -if(typeof rowReference==='object') -row=rowReference +if(typeof rowReference==='object'){row=rowReference} else{if(rowReference=='bottom'){row=tbody.children[tbody.children.length-1]} else if(rowReference=='top'){row=tbody.children[0]}} if(!row) @@ -533,8 +533,7 @@ return var cell=row.children[cellIndex] if(cell) this.tableObj.focusCell(cell)} -Navigation.prototype.focusCellInReplacedRow=function(rowIndex,cellIndex){if(rowIndex==0) -this.focusCell('top',cellIndex) +Navigation.prototype.focusCellInReplacedRow=function(rowIndex,cellIndex){if(rowIndex==0){this.focusCell('top',cellIndex)} else{var focusRow=this.tableObj.findRowByIndex(rowIndex) if(!focusRow) focusRow=this.tableObj.findRowByIndex(rowIndex-1) @@ -614,10 +613,13 @@ Server.prototype.constructor=Server Server.prototype.dispose=function(){BaseProto.dispose.call(this) this.data=null} Server.prototype.getRecords=function(offset,count,onSuccess){var handlerName=this.tableObj.getAlias()+'::onServerGetRecords' -$.request(handlerName,{data:{offset:offset,count:count}}).done(function(data){onSuccess(data.records,data.count)})} -Server.prototype.createRecord=function(recordData,placement,relativeToKey,offset,count,onSuccess){console.log('createRecord')} -Server.prototype.updateRecord=function(key,recordData){console.log('updateRecord')} -Server.prototype.deleteRecord=function(key,newRecordData,offset,count,onSuccess){console.log('deleteRecord')} +this.tableObj.$el.request(handlerName,{data:{offset:offset,count:count}}).done(function(data){onSuccess(data.records,data.count)})} +Server.prototype.createRecord=function(recordData,placement,relativeToKey,offset,count,onSuccess){var handlerName=this.tableObj.getAlias()+'::onServerCreateRecord' +this.tableObj.$el.request(handlerName,{data:{recordData:recordData,placement:placement,relativeToKey:relativeToKey,offset:offset,count:count}}).done(function(data){onSuccess(data.records,data.count)})} +Server.prototype.updateRecord=function(key,recordData){var handlerName=this.tableObj.getAlias()+'::onServerUpdateRecord' +this.tableObj.$el.request(handlerName,{data:{key:key,recordData:recordData}})} +Server.prototype.deleteRecord=function(key,newRecordData,offset,count,onSuccess){var handlerName=this.tableObj.getAlias()+'::onServerDeleteRecord' +this.tableObj.$el.request(handlerName,{data:{key:key,offset:offset,count:count}}).done(function(data){onSuccess(data.records,data.count)})} $.oc.table.datasource.server=Server}(window.jQuery);+function($){"use strict";if($.oc.table===undefined) throw new Error("The $.oc.table namespace is not defined. Make sure that the table.js script is loaded.");if($.oc.table.processor===undefined) $.oc.table.processor={} @@ -688,6 +690,7 @@ var input=document.createElement('input') input.setAttribute('type','text') input.setAttribute('class','string-input') input.value=this.tableObj.getCellValue(cellElement) +if(this.columnConfiguration.readOnly){input.setAttribute('readonly',true)} cellContentContainer.appendChild(input) this.setCaretPosition(input,0) window.setTimeout(this.focusTimeoutHandler,0)} @@ -827,8 +830,7 @@ if(!activeItemElement){activeItemElement=this.itemListElement.querySelector('ul if(activeItemElement) activeItemElement.setAttribute('class','selected')} if(activeItemElement){window.setTimeout(function(){activeItemElement.focus()},0)}}} -DropdownProcessor.prototype.fetchOptions=function(cellElement,onSuccess){if(this.columnConfiguration.options) -onSuccess(this.columnConfiguration.options) +DropdownProcessor.prototype.fetchOptions=function(cellElement,onSuccess){if(this.columnConfiguration.options){onSuccess(this.columnConfiguration.options)} else{var row=cellElement.parentNode,cachingKey=this.createOptionsCachingKey(row),viewContainer=this.getViewContainer(cellElement) viewContainer.setAttribute('class','loading') if(!this.cachedOptionPromises[cachingKey]){var requestData={column:this.columnName,rowData:this.tableObj.getRowData(row)},handlerName=this.tableObj.getAlias()+'::onGetDropdownOptions' diff --git a/modules/backend/widgets/table/assets/js/table.datasource.server.js b/modules/backend/widgets/table/assets/js/table.datasource.server.js index b02ff893a..860e36012 100644 --- a/modules/backend/widgets/table/assets/js/table.datasource.server.js +++ b/modules/backend/widgets/table/assets/js/table.datasource.server.js @@ -47,7 +47,7 @@ */ Server.prototype.getRecords = function(offset, count, onSuccess) { var handlerName = this.tableObj.getAlias()+'::onServerGetRecords' - $.request(handlerName, { + this.tableObj.$el.request(handlerName, { data: { offset: offset, count: count @@ -71,21 +71,18 @@ * The onSuccess callback parameters: records, totalCount. */ Server.prototype.createRecord = function(recordData, placement, relativeToKey, offset, count, onSuccess) { - console.log('createRecord') - // if (placement === 'bottom') { - // // Add record to the bottom of the dataset - // this.data.push(recordData) - // } - // else if (placement == 'above' || placement == 'below') { - // // Add record above or below the passed record key - // var recordIndex = this.getIndexOfKey(relativeToKey) - // if (placement == 'below') - // recordIndex ++ - - // this.data.splice(recordIndex, 0, recordData) - // } - - // this.getRecords(offset, count, onSuccess) + var handlerName = this.tableObj.getAlias()+'::onServerCreateRecord' + this.tableObj.$el.request(handlerName, { + data: { + recordData: recordData, + placement: placement, + relativeToKey: relativeToKey, + offset: offset, + count: count + } + }).done(function(data) { + onSuccess(data.records, data.count) + }) } /* @@ -95,16 +92,13 @@ * - recordData - the record fields. */ Server.prototype.updateRecord = function(key, recordData) { - console.log('updateRecord') - // var recordIndex = this.getIndexOfKey(key) - - // if (recordIndex !== -1) { - // recordData[this.tableObj.options.keyColumn] = key - // this.data[recordIndex] = recordData - // } - // else { - // throw new Error('Record with they key '+key+ ' is not found in the data set') - // } + var handlerName = this.tableObj.getAlias()+'::onServerUpdateRecord' + this.tableObj.$el.request(handlerName, { + data: { + key: key, + recordData: recordData + } + }) } /* @@ -120,20 +114,16 @@ * The onSuccess callback parameters: records, totalCount. */ Server.prototype.deleteRecord = function(key, newRecordData, offset, count, onSuccess) { - console.log('deleteRecord') - // var recordIndex = this.getIndexOfKey(key) - - // if (recordIndex !== -1) { - // this.data.splice(recordIndex, 1) - - // if (this.data.length == 0) - // this.data.push(newRecordData) - - // this.getRecords(offset, count, onSuccess) - // } - // else { - // throw new Error('Record with they key '+key+ ' is not found in the data set') - // } + var handlerName = this.tableObj.getAlias()+'::onServerDeleteRecord' + this.tableObj.$el.request(handlerName, { + data: { + key: key, + offset: offset, + count: count + } + }).done(function(data) { + onSuccess(data.records, data.count) + }) } $.oc.table.datasource.server = Server diff --git a/modules/backend/widgets/table/assets/js/table.helper.navigation.js b/modules/backend/widgets/table/assets/js/table.helper.navigation.js index 6f0893ff0..0483ba2a8 100644 --- a/modules/backend/widgets/table/assets/js/table.helper.navigation.js +++ b/modules/backend/widgets/table/assets/js/table.helper.navigation.js @@ -174,7 +174,7 @@ var curRecordCount = this.getRecordCount() if (placement === 'bottom') - return this.calculatePageCount(curRecordCount+1, this.tableObj.options.recordsPerPage)-1 + return this.calculatePageCount(curRecordCount + 1, this.tableObj.options.recordsPerPage) - 1 // When a row is added above a current row, the current row just moves down, // so it's safe to return the current page index @@ -182,8 +182,8 @@ return this.pageIndex if (placement == 'below') { - if (currentRowIndex == (this.tableObj.options.recordsPerPage-1)) - return this.pageIndex+1 + if (currentRowIndex == (this.tableObj.options.recordsPerPage - 1)) + return this.pageIndex + 1 return this.pageIndex } @@ -193,7 +193,7 @@ Navigation.prototype.getPageAfterDeletion = function(currentRowIndex) { if (currentRowIndex == 0 && this.getRowCountOnPage() == 1) - return this.pageIndex == 0 ? 0 : this.pageIndex-1 + return this.pageIndex == 0 ? 0 : this.pageIndex - 1 return this.pageIndex } @@ -228,10 +228,10 @@ if (!this.paginationEnabled()) return - if (this.pageIndex < this.pageCount-1) { + if (this.pageIndex < this.pageCount - 1) { var self = this - this.gotoPage(this.pageIndex+1, function navDownPageSuccess(){ + this.gotoPage(this.pageIndex + 1, function navDownPageSuccess(){ self.focusCell('top', cellIndex) self = null }) @@ -247,19 +247,20 @@ return var row = this.tableObj.activeCell.parentNode, - newRow = (!ev.shiftKey || isTab) ? - row.previousElementSibling : - row.parentNode.children[0], - cellIndex = forceCellIndex !== undefined ? - forceCellIndex : - this.tableObj.activeCell.cellIndex + newRow = (!ev.shiftKey || isTab) + ? row.previousElementSibling + : row.parentNode.children[0], + cellIndex = forceCellIndex !== undefined + ? forceCellIndex + : this.tableObj.activeCell.cellIndex if (newRow) { var cell = newRow.children[cellIndex] if (cell) this.tableObj.focusCell(cell) - } else { + } + else { // Try to switch to the previous page if that's possible if (!this.paginationEnabled()) @@ -268,7 +269,7 @@ if (this.pageIndex > 0) { var self = this - this.gotoPage(this.pageIndex-1, function navUpPageSuccess(){ + this.gotoPage(this.pageIndex - 1, function navUpPageSuccess(){ self.focusCell('bottom', cellIndex) self = null }) @@ -284,17 +285,18 @@ return var row = this.tableObj.activeCell.parentNode, - newIndex = (!ev.shiftKey || isTab) ? - this.tableObj.activeCell.cellIndex-1 : - 0 + newIndex = (!ev.shiftKey || isTab) + ? this.tableObj.activeCell.cellIndex - 1 + : 0 var cell = row.children[newIndex] - if (cell) + if (cell) { this.tableObj.focusCell(cell) + } else { // Try to navigate up if that's possible - this.navigateUp(ev, row.children.length-1, isTab) + this.navigateUp(ev, row.children.length - 1, isTab) } } @@ -306,14 +308,15 @@ return var row = this.tableObj.activeCell.parentNode, - newIndex = !ev.shiftKey ? - this.tableObj.activeCell.cellIndex+1 : - row.children.length-1 + newIndex = !ev.shiftKey + ? this.tableObj.activeCell.cellIndex + 1 + : row.children.length - 1 var cell = row.children[newIndex] - if (cell) + if (cell) { this.tableObj.focusCell(cell) + } else { // Try to navigate down if that's possible this.navigateDown(ev, 0) @@ -339,12 +342,13 @@ var row = null, tbody = this.tableObj.getDataTableBody() - if (typeof rowReference === 'object') + if (typeof rowReference === 'object') { row = rowReference + } else { if (rowReference == 'bottom') { row = tbody.children[tbody.children.length-1] - } + } else if (rowReference == 'top') { row = tbody.children[0] } @@ -359,8 +363,9 @@ } Navigation.prototype.focusCellInReplacedRow = function(rowIndex, cellIndex) { - if (rowIndex == 0) + if (rowIndex == 0) { this.focusCell('top', cellIndex) + } else { var focusRow = this.tableObj.findRowByIndex(rowIndex) diff --git a/modules/backend/widgets/table/assets/js/table.js b/modules/backend/widgets/table/assets/js/table.js index 447ee0d61..b826a0512 100644 --- a/modules/backend/widgets/table/assets/js/table.js +++ b/modules/backend/widgets/table/assets/js/table.js @@ -215,7 +215,7 @@ if (!this.options.height) this.dataTableContainer = this.tableContainer - else + else this.dataTableContainer = this.buildScrollbar() // Build the data table @@ -240,7 +240,8 @@ // new records can only be added to the bottom of the // table. addBelowButton.textContent = this.options.btnAddRowLabel - } else { + } + else { addBelowButton.textContent = this.options.btnAddRowBelowLabel var addAboveButton = document.createElement('a') @@ -313,7 +314,8 @@ this.unfocusTable() - this.fetchRecords(function onUpdateDataTableSuccess(records, totalCount){ + + this.fetchRecords(function onUpdateDataTableSuccess(records, totalCount) { self.buildDataTable(records, totalCount) if (onSuccess) @@ -322,6 +324,11 @@ if (totalCount == 0) self.addRecord('above', true) + self.$el.trigger('oc.tableUpdateData', [ + records, + totalCount + ]) + self = null }) } @@ -526,7 +533,7 @@ this.elementAddClass(this.activeCell, 'active') } - // If the cell belongs to other row than the currently edited, + // If the cell belongs to other row than the currently edited, // commit currently edited row to the data source. Update the // currently edited row key. var rowKey = this.getCellRowKey(cellElement) @@ -583,7 +590,7 @@ recordData = {}, self = this - recordData[keyColumn] = -1*this.recordsAddedOrDeleted + recordData[keyColumn] = -1 * this.recordsAddedOrDeleted this.$el.trigger('oc.tableNewRow', [ recordData diff --git a/modules/backend/widgets/table/assets/js/table.processor.base.js b/modules/backend/widgets/table/assets/js/table.processor.base.js index 14d14be01..0d63d66cc 100644 --- a/modules/backend/widgets/table/assets/js/table.processor.base.js +++ b/modules/backend/widgets/table/assets/js/table.processor.base.js @@ -174,7 +174,7 @@ /* * Determines whether the specified element is some element created by the - * processor. + * processor. */ Base.prototype.elementBelongsToProcessor = function(element) { return false diff --git a/modules/backend/widgets/table/assets/js/table.processor.dropdown.js b/modules/backend/widgets/table/assets/js/table.processor.dropdown.js index e0c5fb683..c59146f01 100644 --- a/modules/backend/widgets/table/assets/js/table.processor.dropdown.js +++ b/modules/backend/widgets/table/assets/js/table.processor.dropdown.js @@ -192,8 +192,9 @@ } DropdownProcessor.prototype.fetchOptions = function(cellElement, onSuccess) { - if (this.columnConfiguration.options) + if (this.columnConfiguration.options) { onSuccess(this.columnConfiguration.options) + } else { // If options are not provided and not found in the cache, // request them from the server. For dependent drop-downs diff --git a/modules/backend/widgets/table/assets/js/table.processor.string.js b/modules/backend/widgets/table/assets/js/table.processor.string.js index 57dd75499..7aad59288 100644 --- a/modules/backend/widgets/table/assets/js/table.processor.string.js +++ b/modules/backend/widgets/table/assets/js/table.processor.string.js @@ -91,11 +91,16 @@ input.setAttribute('type', 'text') input.setAttribute('class', 'string-input') input.value = this.tableObj.getCellValue(cellElement) + + if (this.columnConfiguration.readOnly) { + input.setAttribute('readonly', true) + } + cellContentContainer.appendChild(input) this.setCaretPosition(input, 0) - // Focus the element in the next frame. + // Focus the element in the next frame. // http://stackoverflow.com/questions/779379/why-is-settimeoutfn-0-sometimes-useful window.setTimeout(this.focusTimeoutHandler, 0) } diff --git a/modules/system/console/OctoberMirror.php b/modules/system/console/OctoberMirror.php index 3f69494bb..16eb49449 100644 --- a/modules/system/console/OctoberMirror.php +++ b/modules/system/console/OctoberMirror.php @@ -26,6 +26,7 @@ class OctoberMirror extends Command protected $description = '(Experimental) Generates a mirrored public folder using symbolic links.'; protected $files = [ + '.htaccess', 'index.php', 'favicon.ico', 'robots.txt', diff --git a/modules/system/traits/PropertyContainer.php b/modules/system/traits/PropertyContainer.php index f7d7a2d2d..3e9cf451c 100644 --- a/modules/system/traits/PropertyContainer.php +++ b/modules/system/traits/PropertyContainer.php @@ -57,7 +57,7 @@ trait PropertyContainer */ public function setProperties($properties) { - return $this->properties = $this->validateProperties($properties); + $this->properties = $this->validateProperties($properties); } /**