How can I implement WooCommerce REST API "orderby" successfully? - wordpress

I'm creating a mobile application using flutter and I'm currently trying to list products with the ability to sort them, but everytime I try to implement the "orderby" parameter, I get this error:
I/flutter ( 5187):
{
"code":"rest_invalid_param",
"message":"Invalid parameter(s): orderby",
"data":
{
"status":400,
"params":
{
"orderby":"orderby is not one of date, id, include, title, slug, price, popularity, and rating."
},
"details":
{
"orderby":
{
"code":"rest_not_in_enum",
"message":"orderby is not one of date, id, include, title, slug, price, popularity, and rating.",
"data":null
}
}
}
}
The code where I get the error:
Future<List<Product>> getProducts({
int pageNumber,
int pageSize,
String strSearch,
String tagName,
String categoryID,
String sortBy,
String sortOrder = "asc",
}) async {
List<Product> data = [];
try {
String parameter = "";
if (strSearch != null) {
parameter += "&search=$strSearch";
}
if (pageSize != null) {
parameter += "&per_page=$pageSize";
}
if (pageNumber != null) {
parameter += "&page=$pageNumber";
}
if (tagName != null) {
parameter += "&tag=$tagName";
}
if (categoryID != null) {
parameter += "&category=$categoryID";
}
if (sortBy != null) {
parameter += "&orderby=$sortBy";
}
if (sortOrder != null) {
parameter += "&order=$sortOrder";
}
String url = Config.url +
Config.productsURL +
"?consumer_key=${Config.key}&consumer_secret=${Config.secret}${parameter.toString()}";
var response = await Dio().get(
url,
options: Options(
headers: {
HttpHeaders.contentTypeHeader: "application/json",
},
),
);
if (response.statusCode == 200) {
data = (response.data as List)
.map(
(i) => Product.fromJson(i),
)
.toList();
}
} on DioError catch (e) {
print(e.response);
}
return data;
}
In a couple of other similar questions, I've been seeing that I need to add a filter looking like this:
add_filter( 'rest_product_collection_params', array( $this, 'filter_add_rest_orderby_params' ), 10, 1 );
add_filter( 'rest_product_cat_collection_params', array( $this, 'filter_add_rest_orderby_params' ), 10, 1 );
function filter_add_rest_orderby_params( $params ) {
$params['orderby']['enum'][] = 'menu_order';
return $params;
}
I wanted to try this, however, I'm not sure if this would work in my case, and does anyone know what specific file I am going to edit to add this filter? I can't seem to find where people put it. (I'm using Wordpress.)

Related

How to get the entire path in Next.js 13 in custom loader function, for server components only?

I have a loader function called getBlogData which is like this:
import { getFromCacheOrApi } from 'Base'
const getBlogData = async () => {
const { pathname } = { pathname: "" }
var url = '/blog/data?'
let matches = /\/blog(\/\d+)?\/?$/.exec(pathname)
if (matches != null) {
const pageNumber = matches[1]
if (pageNumber !== undefined) {
url += `&pageNumber=${pageNumber.replace('/', '')}`
}
}
else {
const secondSegments = ['category', 'tag', 'author', 'search']
if (pathname.split('/').length >= 2 && !secondSegments.includes(pathname.split('/')[2])) {
response.status = 404
return
}
for (let i = 0; i < secondSegments.length; i++) {
const segment = secondSegments[i]
if (pathname.startsWith(`/blog/${segment}`)) {
matches = new RegExp(`(?<=\\/blog\\/${segment}\\/)[^/]+\\/?(\\d+)?\\/?$`).exec(pathname)
if (matches == null) {
response.status = 404
return
}
else {
url += `&${segment}=${encodeURI(matches[0].split('/')[0])}`
const pageNumber = matches[1]
if (pageNumber !== undefined) {
url += `&pageNumber=${pageNumber}`
}
break
}
}
}
}
url = url.replace('?&', '?')
const data = await getFromCacheOrApi(url)
// console.log(params, response.status)
// if (pageNumber && isNaN(pageNumber)) {
// console.log(pageNumber, isNaN(pageNumber))
// response.status = 400
// return
// }
const { seoParameters } = data
return data
}
export default getBlogData
This function is only used in my page which is inside app directory in Next 13, which means that it's a server component, and I don't want to change it to a client component.
However, I need to access request data, in this particular case, the path of the URL.
How can I get that?

How to Update relational Table in Asp.net core Web Api

I create two table Project or Member and i create relational table of project and member table named as project member i want to Update data of that relational table i use angularjs as frontend
This is put method to update the table
[Route("api/updateProjectData")]
[HttpPut]
public IActionResult UpdateProjectData(Project project, ProjectMember projectMember)
{
// query
if (project.ProjectId != project.ProjectId)
{
return BadRequest("Id Mismatched");
}
try
{
_context.Entry(project).State = EntityState.Modified;
_context.SaveChanges();
var memberDetails = _context.ProjectMembers.FirstOrDefault(e => e.ProjectId == project.ProjectId);
_context.Entry(projectMember).State = EntityState.Modified;
_context.SaveChanges();
}
catch (DbUpdateConcurrencyException)
{
if (!ProjectExists(project.ProjectId))
{
return NotFound();
}
else
{
throw;
}
}
return NoContent();
}
private bool ProjectExists(int id)
{
return _context.Projects.Any(e => e.ProjectId == id);
}
This is My frontend Api
$scope.UpdateProjectInfo = (ProjectID) => {
console.log($scope.ProjectID);
console.log($scope.ProjectName);
console.log($scope.ProjectStartDate);
console.log($scope.ProjectEndDate);
console.log($scope.UserStartDate);
$http({
method: 'PUT',
url: 'https://localhost:44307/api/updateProjectData?ProjectId=' + $scope.ProjectID + "&ProjectName=" + $scope.ProjectName + "&Startdate=" + $scope.ProjectStartDate + "&Enddate=" + $scope.ProjectEndDate + "&Status=&UserId=" + $scope.ddlUser + "&RoleId=" + $scope.ddlRole + "&UserStartdate=" + $scope.UserStartDate + "",
// headers: {
// 'Content-type': 'application/json;charset=utf-8'
// }
})
.then(function (response) {
console.log('ResponseUpdated', response.data);
$scope.ProjectName = response.data[0].projectName;
$scope.ddlUser = response.data[0].firstName + " " + response.data[0].lastName;
$scope.ddlRole = response.data[0].roleName;
$scope.ProjectStartDate = response.data[0].startdate;
$scope.ProjectEndDate = response.data[0].enddate;
$scope.UserStartDate = response.data[0].userStartdate;
notify('success', 'Record Updated Successfully.', '');
$scope.closeAddProjectPopup();
}, function (rejection) {
notify('error', rejection.data, '');
});
I successfully update one table But i confused how i update the second one pls tell me how i update

How do I modify wpDataTables cell values using filters?

In wpDataTables, I would like to modify (i.e. conditionally format) each cell value in a specific column for a specific table programmatically using PHP. How would I accomplish this?
First, install the Code Snippets plugin. Then create a new snippet set to "Run Snippet Everywhere" (required for JSON filtering) using the code below. It will filter both HTML and JSON. For more information, refer to wpDataTables - Filters.
function custom_wpdatatables_filter_initial_table_construct($tbl) {
// Edit below.
$table_name_to_modify = 'My Table Name';
$table_column_to_modify = 'my_table_column';
$cell_modification_function = function($value) {
return 'Modified: ' . $value;
};
// Check table name.
if ($tbl->getName() !== $table_name_to_modify) {
return $tbl;
}
$rows = $tbl->getDataRows();
foreach ($rows as &$row) {
if (array_key_exists($table_column_to_modify, $row)) {
$row['intermentobituary'] = $cell_modification_function($row['intermentobituary']);
}
}
$tbl->setDataRows($rows);
return $tbl;
}
add_filter('wpdatatables_filter_initial_table_construct', 'custom_wpdatatables_filter_initial_table_construct', 10, 1);
function custom_wpdatatables_filter_server_side_data($json, $tableId, $get) {
// Edit below.
$table_name_to_modify = 'My Table Name';
$table_column_to_modify = 'my_table_column';
$cell_modification_function = function($value) {
return 'Modified: ' . $value;
};
// Check table name.
$tableData = WDTConfigController::loadTableFromDB($tableId);
if (empty($tableData->content)) {
return $json;
} else if ($tableData->title !== $table_name_to_modify) {
return $json;
}
// Get columns.
$columns = [];
foreach ($tableData->columns as $column) {
// wdt_ID will be first column.
$columns[] = $column->orig_header;
}
// Modify column values.
$json = json_decode($json, true);
$rows = $json['data'];
foreach ($rows as $row_key => $row_value) {
foreach ($row_value as $row_attr_key => $row_attr_value) {
if ( ! empty($columns[$row_attr_key]) && $columns[$row_attr_key] === $table_column_to_modify) {
$rows[$row_key][$row_attr_key] = $cell_modification_function($row_attr_value);
}
}
}
$json['data'] = $rows;
return json_encode($json);
}
add_filter('wpdatatables_filter_server_side_data', 'custom_wpdatatables_filter_server_side_data', 10, 3);

next.js middleware, NextResponse.redirect() not working when using map or foreach, but it works when using for loops

//this won't work
rules.filter(rule => rule.type === 'redirect' && new RegExp(rule.rule).exec(pathname.slice(1)))
.map(rule => {
console.log('match');
const url = req.nextUrl.clone()
url.pathname = rule.destination
return NextResponse.redirect(url)
})
//this does work
for (let rule of rules) {
const regex: RegExp = new RegExp(rule.rule)
if(regex.exec(pathname.slice(1)) && rule.type === 'redirect') {
console.log('match');
const url = req.nextUrl.clone()
url.pathname = rule.destination
return NextResponse.redirect(url)
}
}
the middleware is already running well with de for loop
Reddit gave me the solution, I leave it here
A return statement inside map simply adds to the map output array.
A return statement in a for loop exits the function.
Next.js will redirect if a middleware returns NextResponse.redirect(), as you would if you used a for loop and return statement.
let result
rules.filter(rule => rule.type === 'redirect' && new RegExp(rule.rule).exec(pathname.slice(1)))
.map(rule => {
console.log('match');
url.pathname = rule.destination
result = NextResponse.redirect(url)
})
return result
Can reproduce this issue. We had to convert:
PRIVATE_ROUTES.forEach((route) => {
if (url.pathname.includes(route)) {
if (!authenticated) {
url.pathname = Routes.auth.signIn;
return NextResponse.redirect(url);
} else if (
req.cookies.get('auth-next-url') &&
url.pathname !== req.cookies.get('auth-next-url')
) {
url.pathname = req.cookies.get('auth-next-url')!;
return NextResponse.redirect(url);
}
}
});
To this:
for (let route of PRIVATE_ROUTES) {
if (url.pathname.includes(route)) {
if (!authenticated) {
url.pathname = Routes.auth.signIn;
return NextResponse.redirect(url);
} else if (
req.cookies.get('auth-next-url') &&
url.pathname !== req.cookies.get('auth-next-url')
) {
url.pathname = req.cookies.get('auth-next-url')!;
return NextResponse.redirect(url);
}
}
}

AngularFire2 query, join or filter with foreign keys from another firebase table

I have this firebase data structure
{
members: {
m1: {
lastName: "smith",
firstName: "john"
},
m2: {
lastName: "abc",
firstName: "mike"
}
},
userFavs: {
u1: {
m1:true
},
u2: {
m2:true
}
}
}
In my service, I have this method:
getMembers(): FirebaseListObservable<any[]> {
return this.af.database.list('/members',{
query: {
orderByChild: 'firstName'
}
});
}
In members page TS file, I have method to do search:
setFilteredItems(){
if (this.searchTerm == null || this.searchTerm == ''){
this.members = this.membersSvc.getMembers()
.map((members) => {return members});
}else{
//return items.filter(item => item.name.toLowerCase().indexOf(args[0].toLowerCase()) !== -1);
this.members = this.membersSvc.getMembers()
.map((members) =>
members.filter(member => member.lastName.toLowerCase().indexOf(this.searchTerm.toLowerCase()) !== -1 || member.firstName.toLowerCase().indexOf(this.searchTerm.toLowerCase()) !== -1));
}
}
The search for members is working fine. Now I am adding 2 buttons below the search bar, All and Favorites. A user can add a member in his/her favorites. In search, the app needs to be able to filter the results with member keys that exists in the user favorites.
How can I add the additional filter of member keys that exists in the userFavs node?
I added the additional filter by getting the array of userFavs keys. So in my user service I have a method:
getUserFavKeys(){
let favKeys = [];
const userKey = this.authService.getActiveUser().uid;
let url = `/userCircles/${userKey}`;
this.af.database.list(url, { preserveSnapshot: true})
.subscribe(itemKeys=>{
itemKeys.forEach(itemKey => {
//console.log(itemKey.key);
favKeys.push(itemKey.key);
});
})
return favKeys;
}
Then in the component ngOnInit method, I initialized the array of keys:
this.favKeys = this.userSvc.getUserFavKeys();
And when the circles is selected:
onCirclesSelected(){
this.searching = false;
this.members = this.membersSvc.getMembers()
.map((members) =>
members.filter(member => this.userCircles.indexOf(member.$key) !== -1)
);
if (this.searchTerm == null || this.searchTerm == ''){
//do nothing
}else{
//filter w the search text
this.members = this.members
.map((members) =>
members.filter(member => member.lastName.toLowerCase().indexOf(this.searchTerm.toLowerCase()) !== -1 || member.firstName.toLowerCase().indexOf(this.searchTerm.toLowerCase()) !== -1));
}
}
Hope that helps to anyone that needs the same search feature.

Resources