Compiler Error Message: CS1061

Please help me..

When i code in my PC for this programming it is running without any error, but when i release it to server i Encountered error Compiler Error Message: CS1061: 'ASP. registration_aspx' does not contain a definition for 'btnDeactivate_Onclick' and no extension method 'btnDeactivate_Onclick' accepting a first argument of type 'ASP. registration_aspx' could be found (are you missing a using directive or an assembly reference?)

aspx code :

 <asp:GridView ID="gvData" runat="server" AllowPaging="true" PageSize="20" AutoGenerateColumns="false" 
                    PagerSettings-Visible="false" HeaderStyle-CssClass="GV_Header " RowStyle-CssClass="GV_Row" EnableModelValidation="True" 
                    Width="100%" OnSelectedIndexChanging="btnDeactivate_Onclick" OnRowCommand="gvData_RowCommand"  
                 DataKeyNames="rebate_code" >

 <asp:TemplateField HeaderText="">                    
                            <ItemStyle HorizontalAlign="Center" Width="50px"></ItemStyle>
                            <ItemTemplate>
                              <asp:ImageButton ImageUrl="~/Images/comm_img/disable.png" ID="Deactivate" runat="server" 
                               ToolTip="Deactivate" CommandName="Select"      
                               CommandArgument='<%# Eval("rebate_code") %>' />                            
                            </ItemTemplate>
                        </asp:TemplateField>

aspx.cs code :

 protected void btnDeactivate_Onclick(object sender, GridViewSelectEventArgs e)

    {
        //only fanliyee & chloe can deactivate the lump sum rebate
            if ((Session["LoginName"].ToString()) == "fanliyee" || (Session["LoginName"].ToString()) == "chloelimenghui")
            {
            string RebateCode = gvData.DataKeys[e.NewSelectedIndex].Value.ToString();
            GridViewRow row = (GridViewRow)gvData.Rows[e.NewSelectedIndex];
            int rowUpdate = 0;
            DataSet result = new DataSet();
            result = BO_Rebate.Deactivate_RebateLS_List(Session["LoginName"].ToString(), RebateCode);
            rowUpdate = Convert.ToInt32(result.Tables[0].Rows[0]["ReturnValue"]);
            if (rowUpdate != 0)
            {
                BindData();
                //gvData.EditIndex = -1;
                //gvData.DataBind();
                Page.ClientScript.RegisterStartupScript(this.GetType(), "", "alert('Deactivated succesfully');", true);
                return;
            }
            else
            {
                Page.ClientScript.RegisterStartupScript(this.GetType(), "", "alert('Deactivated failed !');", true);

                return;
            }
        }
        else
        {
            Page.ClientScript.RegisterStartupScript(this.GetType(), "", "alert('User is not eligible to perform this function !');", true);

            return;
        }
    }

Test Your WordPress Site Security – 6 Free WordPress Security Scanners

We think our security plugin, Defender, is pretty darn good, but we’d never tell you to put all your eggs in one basket. Even with a super-reliable and robust security plugin, you should still carry out extra checks on your site’s security…

Gone are the days where the only way to infiltrate someone’s computer or accounts was to send them a virus disguised as a pdf or manually guess their passwords.

Nowadays, hacking is easy. It’s automated.

Bots can brute-force their way into a site, create fake administrator accounts, and scan the network for vulnerabilities and valuable files in a matter of seconds.

This means that you no longer need a determined enemy in order to be the victim of an attack.

And since attacks are always on the rise, it makes sense to take whatever precautions are available in order to protect your site and ultimately, your visitors.

One of these precautions is simply taking the time to check your site from a few different sources.

Read on as we take a look at some of the best free tools out there.

1. Defender
2. WordPress Tools
3. wpRecon
4. VirusTotal
5. Mozilla Observatory
6. Google Transparency Report

1. Defender

Hopefully, you’re already using Defender to protect your site against malicious attacks, however, did you know it has an awesome scan feature, as well as a comprehensive rundown of things you can do to improve your site security?

Let’s start with the scan.

To begin a scan, click on Defender’s Malware Scanning option in the WordPress sidebar.

 

 

Screenshot of Defender about to start a scan
Click Run Scan.

Defender will then highlight any files that it thinks are suspicious, such as core files which have been edited or don’t come as standard.

Screenshot of Defender's scan results showing two potentially malicious files.
Defender will check your core files against the originals in the WordPress repository.

You’ll need to check through the files to decide whether they pose a risk, or whether they are changes you’ve made yourself.

You then have three options:

  • If you don’t think a certain file should exist at all, you can delete it.
  • If you believe a core file has been tampered with, you can restore it to the original – Defender will replace it with a fresh copy.
  • If you trust these files, you can ask Defender to ignore them in future scans.
Screenshot of a suspicious file in Defender showing the snipper of code.
Defender will even show you the code in question.

Ensuring that no code has been tampered with is a great way to keep on top of your site security.

Defender goes one step further. It can carry out an overall check on your site security to give you recommendations if there are vulnerabilities on your site that could easily be fixed.

Simply head to the Recommendations section to find out if Defender has picked up any vulnerabilities.

Screenshot of the security recommendations with Defender.
It will give you a list of all the current recommended steps.

You can click on each item individually to see more information. Defender can even provide you with instructions to fix it!

The code needed to fix the issue.
The instructions and code are provided.

Defender will also let you know what you’re doing right, by listing all the precautions you have already taken.

Simply navigate to the Actioned tab on the left of Defender’s screen.

Screenshot of all the actioned vulnerabilities.
Aim to get all recommendations into the Actioned column for the best chance of securing your site.

Like what you see?

Check out our full guide on how to get the most out of Defender, and if you host with us, take a look at how it integrates perfectly with The Hub.

2. WordPress Tools

The WordPress Tools section might not be somewhere you check into often, however, the Site Health menu can be pretty valuable, and is worth the odd visit.

This tool also offers more than just security recommendations and will provide more information than any of the external tools as it is linked directly with your site.

Screenshot of the WordPress tools recommendations.
Even the Performance suggestions can help with security – better update the PHP version!

If you click on each recommendation, you will get some pretty useful further details.

Screenshot of the list of inactive themes.
This information can make keeping on top of inactive themes and plugins so much easier!

You can also check out the list of passed tests so that you know what you’re doing right.

Screenshot of the 18 rectified issues.
It’s always reassuring to know when things are taken care of.

It’s built right into your WordPress installation so it should only take a minute or two to carry out a quick check every once in a while.

3. wpRecon

It’s good to get an idea of any information about your site which is publicly accessible, as this can be used by hackers to find ways to compromise your security.

One of the best ways to find out what information is readily available is by using a third-party tool that isn’t linked to your site.

wpRecon is one of these tools.

Simply input the URL of the site you want to test.

Screenshot of the box from which you can run your scan.
You can test any site you wish.

The test will give you a variety of results, with the first set being in relation to your server type, IP address, and a check of the version of WordPress you’re running.

Screenshot of information obtained from the WPrecon scan.
This is all information that can be obtained with just your URL!

It will also inform you of any plugins that are reading the HTML source of the website’s front page, check for information it can find about the theme, and try to list the contents of uploads and plugins folders.

Screenshot of the results of the test which tries to access your folders.
It is good to be aware if Directory Indexing is enabled on your site.

A routine check using a tool such as wpRecon will help you identify if there are any big holes, ready for hackers to walk through.

4. VirusTotal

VirusTotal is another free online tool for scanning sites, documents, and IP addresses. It has a database of over 70 antivirus scanners and URL/domain blacklisting services.

Screenshot of some of the partners that VirusTotal uses.
These are just a few of the databases that VirusTotal checks.

If your site is clean, you should be good to go, however, if any of the databases pick up something malicious, it could be that you have malware.

If this is the case, it could be worth running a full malware scan.

You can also check some further details regarding your site.

Screenshot of the result of the outgoing links check.
It’s good to check whether any external links have been added to your site without your knowledge.

VirusTotal shares the result of the scan with the examining partners that it uses. This grows their virus and knowledge databases, helping to fight the fight against malware and hackers.

5. Mozilla Observatory

Mozilla Observatory is slightly different from the tools we’ve looked at above, as it offers a few separate types of tests.

When you first run the scan, it will test vulnerabilities in relation to HTTP. It will then give your site a score in the form of a letter.

Screenshot of the result of the test.
Yeah, not the best score – but this is why checks like this are useful!

Scroll down to see which of the tests you failed (if any).

Screenshot of the test scores.
You will be able to see how you scored on all of the 11 tests.

Click on the name of each test to be taken to a page created by Mozilla which fully explains what it means.

After the first scan, you can also initiate further ones to check if access to your site can be gained through SSH (it would be very concerning if this was the case!) and extra tests with third-party companies ImmuniWeb, securityheaders.com, and hstspreload.org.

6. Google Transparency Report

Google’s Transparency Report isn’t really the answer for checking for vulnerabilities on your own site, however, there’s a reason it made it to this list.

The reason it won’t be much help when it comes to your own site is that it only tells you whether or not it finds anything unsafe, it doesn’t tell you what the unsafe content is.

This makes it pretty redundant when checking on your own site but can come in useful when checking a site you want to visit.

If you’re nervous about visiting a URL for the first time, you can simply input it into Google Transparency Report’s search bar, and let it check it out for you.

Google transparency search results.
It provides a basic yes or no answer as to whether the site is safe to visit.

So yes, whilst it may not be the answer to checking for holes in your site security, it’s a pretty good tool to have in your bag!

Stay One Step Ahead

Carry out regular checks on your site using a variety of tools to make sure you identify any vulnerabilities before hackers or bots sniff them out.

Many of the issues picked up by these tools are quick and easy fixes, so schedule in regular checks as part of your site security process.

If you want to know how to make sure you haven’t missed anything when it comes to setting up the protection for your WordPress site, be sure to check out our 16-step checklist to total site lockdown.

And with this being #SecurityMonth you can currently get 35% off your first year of our Security & Backups Pack featuring Defender Pro, Snapshot Pro, Shipper Pro, and Automate. Click on the coupon below to unlock the exclusive deal.

35% Off Security & Backups Pack

The Truth About the 10X Developer

Introduction

We’ve all heard of the concept of a 10X Developer. Most likely, when you first encountered it, the context was that of a myth or urban legend. I don’t agree. As a reformed psychologist I’m fascinated by legends that are “sticky.” No story hangs around for as long as this unless it contains an element of truth. Or perhaps addresses some deep seated need. In this article I would like to convince you that the 10X Developer is a real, if very rare, individual. More like a Rhino than a Sasquatch.

The Really Real Developers

If I rate myself honestly as a developer, from a scale of one to ten, then I’m about a six. I peaked at seven in my mid-thirties and have been in gradual decline ever since.

An Approach to Cloud Transformation and Cloud Migration

Overview

The ongoing COVID 19 pandemic is creating new challenges to almost all industries. It is causing a significant impact on business and operating models. Organizations are rethinking, "how to make business resilient for such large disruptions," " how to innovate faster and enable new business services to customers," "how to reduce TCO," and "how to enable better connectivity and collaborations." Such challenges existed before the pandemic era as well, but have become more relevant and important now.

Businesses that have already embarked on their cloud journey have shown greater resiliency and responsiveness to this pandemic. In the near future, it's expected that cloud adoption will significantly increase across industries with a combination of different cloud service models (SaaS, PaaS, IaaS) along with hybrid and multi-cloud topologies. Cloud hosting will become a new essential IT service for businesses.

A well-defined approach for cloud transformation is expected to realize business goals, cost savings, and strategic benefits. This article will briefly outline the elements of a typical approach for application cloud migration, modernization, and transformation. The article combines portfolio rationalization methods that can identify potential savings by reducing spending on non-valuable portfolios, along with cloud migration methods to realize the benefits of the cloud. This article will explain the methodical approach to a successful cloud transformation.

JavaScript vs Other Popular Languages of the 21st Century

The trends in the programming industry have changed so much in the past decade. One such evolution was seen in the web development industry. In the earlier days, web development originally just dealt with the development of web pages and websites for the intranet and internet. 

As time has passed, it has become more focused on creating complex and detailed web, mobile, and desktop applications. 

WordPress for Android Previews New Story Posts Feature, Now in Public Beta

WordPress users on Android may have noticed a new prompt in the mobile app for publishing Story posts. This feature is now in public beta in the Android app, ahead of an upcoming launch on the WordPress iOS app. Stories will also coming to the Block editor on WordPress.com in early 2021.

Early access to Story posts is available in version 16.3+ of the app, released in mid-December. The prompt appears at the bottom of the site management screen. Selecting a Story post immediately takes you to your phone’s media where you can add photos or a video.


The mobile app’s implementation of the Stories feature is different from other platforms, like Instagram and Facebook, in several key ways. Most importantly, WordPress stories are not ephemeral. They live permanently on your site and anyone can view them after they are published. WordPress.com’s documentation for the block highlights a few differences:

  • Posts with Stories won’t disappear after 24 hours. 
  • The Story content can be added to and edited after publishing. 
  • Anyone visiting your site can view the Story. 
  • You can share your Story on any platform using the post permalink.

After testing the feature, I can confirm a few more differences. While the WordPress app’s implementation transcends other platforms’ limitations on the duration of the story’s visibility, it lacks basic features that users have come to expect from other apps. It doesn’t support animated gifs, effects, location, stickers, music, and other embellishments that make stories such a creative social medium. At the moment, the only thing you can do is add colored text with a background.

Videos work as Stories, too, but they don’t seem to have the same preview with a thumbnail image. It’s just a generic placeholder for now. That may be something the team is still working on, but I logged an issue on GitHub for it, in case it’s a bug.

In the interest of owning your own content, I can see it being useful to create stories on your own website and share them to other networks. The current implementation is basically a fullscreen slideshow. It is not yet more compelling than what social networks offer, but it looks like WordPress for iOS plans to expand on these features using the open source Kanvas library from Tumblr.

Kanvas makes it possible to add effects, drawings, text, stickers, and make GIFs from existing media or the camera. If you have ever used the Tumblr iOS app then you have seen Kanvas in action in the camera, media editor, GIF maker, and media posting tool. It should make for a more exciting Stories implementation on iOS, with features on par with what users have come to expect from other platforms. Something similar for Android may be in the works and this post will be updated as soon as we receive comments from the mobile team.

Traditional iPaaS Doesn’t Work for Software Companies – Here’s Why

It’s no surprise that software integration is a hot topic these days. Or that there’s a growing number of iPaaS (Integration Platform as a Service) solutions that help companies build integrations between all the different applications they use.

Businesses are using more and more unique applications as part of their day-to-day operations. That presents challenges like siloed data and disjointed workflows, creating a need to easily connect those applications.

What Is Application Modernization?

The world is undergoing significant digitization today. Almost every business, irrespective of its industry, is digitizing its entire business model by shifting it to apps. Multiple sectors are undergoing digital transformation to efficiently handle their businesses and make themselves more accessible to their clients. According to Statista, global spending on digital transformation will reach USD 2.3 trillion by 2023.

Cloud computing plays a considerable role in digital business transformation happening at such a large scale, especially in the pandemic-hit 2020. It has provided people with cost-effective solutions to manage everything electronically without worrying about the basic infrastructure of their applications and the responsibilities that come with it. According to research, the cloud computing market has grown up to USD 371.4 billion in 2020 and is expected to grow up to USD 832.1 billion by 2025.

What Is an API Gateway?

In this article, we are going to use Zato in its capacity as a multi-protocol Python API gateway - we will integrate a few popular technologies, accepting requests sent over protocols commonly used in frontend systems, enriching and passing them to backend systems, and returning responses to the API clients using their preferred data formats. But first, let's define what an API gateway is.

Clearing up the Terminology

Although we will be focusing on complex API integrations later, to understand the term API gateway we first need to give proper consideration to the very term gateway.

If Testing Was a Race, Data Would Win Every Time

Okay, so that title doesn’t make complete sense. However, if you read to the end of this article, all will become clear. I’m first going to discuss some of the persistent barriers to in-sprint testing and development. I will then discuss a viable route to delivering rigorously tested systems in short sprints.

The two kingpins in this approach will be data and automation, working in tandem to convert insights about what needs testing into rigorous automated tests. But first, let’s consider why it remains so challenging to design, develop and test in-sprint.

What Do We Mean by Machine Learning?

The goal of artificial intelligence is to create a machine that can mimic a human mind and to do that, of course, it needs learning capabilities. However, it is more than just about learning. It’s about reasoning, knowledge representation, and even things like abstract thinking. 

Machine learning, on the other hand, is solely focused on writing software that can learn from past experiences. One thing you might find astounding is that machine learning is more closely related to data mining and statistics than it is to AI. Why is that? First, we need to know what we mean by machine learning.

Why Cloud Service Providers Are Important for Small Businesses

Cloud services are essential for modern businesses. If you want to know why, read on for the details!

We’re living in a world where we see something new every other day across the world. Cloud is one of the innovations that has been helping modern businesses transform their wide-ranging processes over the past few years. Cloud solutions like Microsoft Azure, Bitrix, and Bitrix 24 are becoming the mainstream.

Kinsta Launches Free Local WordPress Development Tool

Kinsta, a managed WordPress hosting company, announced its local development tool named DevKinsta earlier today. The tool allows developers to spin up new WordPress sites, including multisite support, in moments. Each site is automatically configured with Nginx, PHP, and MySQL.

DevKinsta packages Adminer, an open-source database manager. The system also includes an SMTP server and email inbox for testing outgoing emails locally.

“This is the first version of the tool, let’s say the MVP, but we have a dedicated development team supporting and adding a lot of new features to it,” said Tom Zsomborgi, Kinsta’s Chief Business Officer.

Developers can run and test HTTPS support and enable WP_DEBUG at the flip of a switch. Kinsta web hosting customers can also deploy their sites directly from the interface.

It took me around an hour to get the system set up and running. To be more exact, I spent 53 minutes. Close enough. Between having to sign out, restart my laptop, and waiting for various pieces to install, I at least managed to get a little laundry done in those dull, in-between moments.

DevKinsta installation screen with Docker in the background.
Installing DevKinsta on Windows.

The setup process was not a completely pain-free affair. However, the price of admission to use this tool — a little bit of my time — was well worth it.

Let me be clear. I have tested far worse systems. Even with over 15 years of development experience under my belt, I have utterly failed at setting up other local dev environments. For DevKinsta to simply get me to the finish line is a success.

However, I like simple things, and I prefer them to move along relatively quickly. I am accustomed to a 20-minute XAMPP setup. While it may not be as fancy or have the bells and whistles of more sophisticated development tools, it gets the job done and rarely doles out headaches.

The holdup was setting up Windows Subsystem for Linux (WSL 2) and Docker, which are both requirements. Jump-starting DevKinsta itself was a breeze. And, as an old-school XAMPP user, DevKinsta’s ease of use has pulled me in enough to do more than just give it a passing glance. I could actually see myself using this on a day-to-day basis.

In short, I am sold. DevKinsta is a tool all WordPress developers should at least spin up once.

Thus far, the feedback on Twitter has been generally positive. However, Linux users may have to wait a bit because the tool is only available for macOS and Windows at the moment.

“I love seeing companies releasing local development tools but I wish more would offer their services to Linux users,” tweeted WordPress developer Chad McCullough. “There are a lot of us developers out there running Linux.” The Kinsta team responded that the tool will eventually support Linux and that news is forthcoming.

Single site creation process using the DevKinsta development tool.
Spinning up a new WordPress site.

The simple and straightforward UI is what makes this tool useful. Most developers do not need overly complicated configurations and options. They simply need to launch an environment that lets them work on their own projects. Anything beyond the basics far too often gets in the way.

DevKinsta makes it easy to launch and manage multiple development installs. Developers can also switch PHP versions via a simple dropdown — versions 7.2 – 8.0 are currently supported.

DevKinsta's site management screen, which lists all sites and has a button for adding a new site.
Site management screen.

The obvious comparison for DevKinsta will be against Local by Flywheel, which has increasingly become a primary tool for many WordPress developers.

Zsomborgi explained why the company thinks DevKinsta is a better option. “In our case, Docker is an important part here. Local doesn’t use virtualization in the background. Local has to install every piece of the environment to the host machine (NGINX, apache, different PHP versions, etc.). DevKinsta encapsulates these technologies into containers. Containers do make things easier for maintaining different applications without interrupting the host OS or installing many of the dependencies that are not required. We pretty much don’t touch the host OS, but have Docker as our main dependency to run the applications on their own environments.”

He said this speeds up the upgrade process and makes it easier to maintain bug fixes and send out security patches. He also said that because each application runs on its own Kernel namespace, any security issues should not affect the host OS.

“If the user is comfortable enough with Docker, he can extend DevKinsta features,” said Zsomborgi. “For example, he can monitor the usage of the container, or the PHP usage specifically as an example with docker monitoring tools that comes out of the box with Docker installation. The user can install any utility inside DevKinsta containers without touching the host OS and use applications that are not supported on Windows, for example.”

One of the use cases he mentioned was installing a benchmark tool to get statistics about site performance. This can be installed inside the Nginx container as a sidecar or separate container.

“In the past, Local didn’t use exactly Docker,” said Zsomborgi. “They used VirtualBox + DockerMachine. We tried it, and it was a bit painful. But without VirtualBox, DevKinsta can be more stable and scalable. So we use Docker without VirtualBox. It also needs virtualization, but nowadays, there are fewer Windows computers that have disabled virtualization by default.”

I need a software that can automatically login

I need a software that can automatically log into a series of accounts to a website, available data acount list, we need software to automatically log in continuously to check whether the account is alive or dead and check. check nickname in the game, and amount in the account

Rendering the WordPress philosophy in GraphQL

WordPress is a CMS that’s coded in PHP. But, even though PHP is the foundation, WordPress also holds a philosophy where user needs are prioritized over developer convenience. That philosophy establishes an implicit contract between the developers building WordPress themes and plugins, and the user managing a WordPress site.

GraphQL is an interface that retrieves data from—and can submit data to—the server. A GraphQL server can have its own opinionatedness in how it implements the GraphQL spec, as to prioritize some certain behavior over another.

Can the WordPress philosophy that depends on server-side architecture co-exist with a JavaScript-based query language that passes data via an API?

Let’s pick that question apart, and explain how the GraphQL API WordPress plugin I authored establishes a bridge between the two architectures.

You may be aware of WPGraphQL. The plugin GraphQL API for WordPress (or “GraphQL API” from now on) is a different GraphQL server for WordPress, with different features.

Reconciling the WordPress philosophy within the GraphQL service

This table contains the expected behavior of a WordPress application or plugin, and how it can be interpreted by a GraphQL service running on WordPress:

CategoryWordPress app expected behaviorInterpretation for GraphQL service running on WordPress
Accessing dataDemocratizing publishing: Any user (irrespective of having technical skills or not) must be able to use the softwareDemocratizing data access and publishing: Any user (irrespective of having technical skills or not) must be able to visualize and modify the GraphQL schema, and execute a GraphQL query
ExtensibilityThe application must be extensible through pluginsThe GraphQL schema must be extensible through plugins
Dynamic behaviorThe behavior of the application can be modified through hooksThe results from resolving a query can be modified through directives
LocalizationThe application must be localized, to be used by people from any region, speaking any languageThe GraphQL schema must be localized, to be used by people from any region, speaking any language
User interfacesInstalling and operating functionality must be done through a user interface, resorting to code as little as possibleAdding new entities (types, fields, directives) to the GraphQL schema, configuring them, executing queries, and defining permissions to access the service must be done through a user interface, resorting to code as little as possible
Access controlAccess to functionalities can be granted through user roles and permissionsAccess to the GraphQL schema can be granted through user roles and permissions
Preventing conflictsDevelopers do not know in advance who will use their plugins, or what configuration/environment those sites will run, meaning the plugin must be prepared for conflicts (such as having two plugins define the SMTP service), and attempt to prevent them, as much as possibleDevelopers do not know in advance who will access and modify the GraphQL schema, or what configuration/environment those sites will run, meaning the plugin must be prepared for conflicts (such as having two plugins with the same name for a type in the GraphQL schema), and attempt to prevent them, as much as possible

Let’s see how the GraphQL API carries out these ideas.

Accessing data

Similar to REST, a GraphQL service must be coded through PHP functions. Who will do this, and how?

Altering the GraphQL schema through code

The GraphQL schema includes types, fields and directives. These are dealt with through resolvers, which are pieces of PHP code. Who should create these resolvers?

The best strategy is for the GraphQL API to already satisfy the basic GraphQL schema with all known entities in WordPress (including posts, users, comments, categories, and tags), and make it simple to introduce new resolvers, for instance for Custom Post Types (CPTs).

This is how the user entity is already provided by the plugin. The User type is provided through this code:

class UserTypeResolver extends AbstractTypeResolver
{
  public function getTypeName(): string
  {
    return 'User';
  }

  public function getSchemaTypeDescription(): ?string
  {
    return __('Representation of a user', 'users');
  }

  public function getID(object $user)
  {
    return $user->ID;
  }

  public function getTypeDataLoaderClass(): string
  {
    return UserTypeDataLoader::class;
  }
}

The type resolver does not directly load the objects from the database, but instead delegates this task to a TypeDataLoader object (in the example above, from UserTypeDataLoader). This decoupling is to follow the SOLID principles, providing different entities to tackle different responsibilities, as to make the code maintainable, extensible and understandable.

Adding username, email and url fields to the User type is done via a FieldResolver object:

class UserFieldResolver extends AbstractDBDataFieldResolver
{
  public static function getClassesToAttachTo(): array
  {
    return [
      UserTypeResolver::class,
    ];
  }

  public static function getFieldNamesToResolve(): array
  {
    return [
      'username',
      'email',
      'url',
    ];
  }

  public function getSchemaFieldDescription(
    TypeResolverInterface $typeResolver,
    string $fieldName
  ): ?string {
    $descriptions = [
      'username' => __("User's username handle", "graphql-api"),
      'email' => __("User's email", "graphql-api"),
      'url' => __("URL of the user's profile in the website", "graphql-api"),
    ];
    return $descriptions[$fieldName];
  }

  public function getSchemaFieldType(
    TypeResolverInterface $typeResolver,
    string $fieldName
  ): ?string {
    $types = [
      'username' => SchemaDefinition::TYPE_STRING,
      'email' => SchemaDefinition::TYPE_EMAIL,
      'url' => SchemaDefinition::TYPE_URL,
    ];
    return $types[$fieldName];
  }

  public function resolveValue(
    TypeResolverInterface $typeResolver,
    object $user,
    string $fieldName,
    array $fieldArgs = []
  ) {
    switch ($fieldName) {
      case 'username':
        return $user->user_login;

      case 'email':
        return $user->user_email;

      case 'url':
        return get_author_posts_url($user->ID);
    }

    return null;
  }
}

As it can be observed, the definition of a field for the GraphQL schema, and its resolution, has been split into a multitude of functions:

  • getSchemaFieldDescription
  • getSchemaFieldType
  • resolveValue

Other functions include:

This code is more legible than if all functionality is satisfied through a single function, or through a configuration array, thus making it easier to implement and maintain the resolvers.

Retrieving plugin or custom CPT data

What happens when a plugin has not integrated its data to the GraphQL schema by creating new type and field resolvers? Could the user then query data from this plugin through GraphQL?

For instance, let’s say that WooCommerce has a CPT for products, but it does not introduce the corresponding Product type to the GraphQL schema. Is it possible to retrieve the product data?

Concerning CPT entities, their data can be fetched via type GenericCustomPost, which acts as a kind of wildcard, to encompass any custom post type installed in the site. The records are retrieved by querying Root.genericCustomPosts(customPostTypes: [cpt1, cpt2, ...]) (in this notation for fields, Root is the type, and genericCustomPosts is the field).

Then, to fetch the product data, corresponding to CPT with name "wc_product", we execute this query:

{
  genericCustomPosts(customPostTypes: "[wc_product]") {
    id
    title
    url
    date
  }
}

However, all the available fields are only those ones present in every CPT entity: title, url, date, etc. If the CPT for a product has data for price, a corresponding field price is not available. wc_product refers to a CPT created by the WooCommerce plugin, so for that, either the WooCommerce or the website’s developers will have to implement the Product type, and define its own custom fields.

CPTs are often used to manage private data, which must not be exposed through the API. For this reason, the GraphQL API initially only exposes the Page type, and requires defining which other CPTs can have their data publicly queried:

The plugin provides an interface for whitelisting CPTs to be exposed in the API.

Transitioning from REST to GraphQL via persisted queries

While GraphQL is provided as a plugin, WordPress has built-in support for REST, through the WP REST API. In some circumstances, developers working with the WP REST API may find it problematic to transition to GraphQL.

For instance, consider these differences:

  • A REST endpoint has its own URL, and can be queried via GET, while GraphQL, normally operates through a single endpoint, queried via POST only
  • The REST endpoint can be cached on the server-side (when queried via GET), while the GraphQL endpoint normally cannot

As a consequence, REST provides better out-of-the-box support for caching, making the application more performant and reducing the load on the server. GraphQL, instead, places more emphasis in caching on the client-side, as supported by the Apollo client.

After switching from REST to GraphQL, will the developer need to re-architect the application on the client-side, introducing the Apollo client just to introduce a layer of caching? That would be regrettable.

The “persisted queries” feature provides a solution for this situation. Persisted queries combine REST and GraphQL together, allowing us to:

  • create queries using GraphQL, and
  • publish the queries on their own URL, similar to REST endpoints.

The persisted query endpoint has the same behavior as a REST endpoint: it can be accessed via GET, and it can be cached server-side. But it was created using the GraphQL syntax, and the exposed data has no under/over fetching.

Extensibility

The architecture of the GraphQL API will define how easy it is to add our own extensions.

Decoupling type and field resolvers

The GraphQL API uses the Publish-subscribe pattern to have fields be “subscribed” to types.

Reappraising the field resolver from earlier on:

class UserFieldResolver extends AbstractDBDataFieldResolver
{
  public static function getClassesToAttachTo(): array
  {
    return [UserTypeResolver::class];
  }

  public static function getFieldNamesToResolve(): array
  {
    return [
      'username',
      'email',
      'url',
    ];
  }
}

The User type does not know in advance which fields it will satisfy, but these (username, email and url) are instead injected to the type by the field resolver.

This way, the GraphQL schema becomes easily extensible. By simply adding a field resolver, any plugin can add new fields to an existing type (such as WooCommerce adding a field for User.shippingAddress), or override how a field is resolved (such as redefining User.url to return the user’s website instead).

Code-first approach

Plugins must be able to extend the GraphQL schema. For instance, they could make available a new Product type, add an additional coauthors field on the Post type, provide a @sendEmail directive, or anything else.

To achieve this, the GraphQL API follows a code-first approach, in which the schema is generated from PHP code, on runtime.

The alternative approach, called SDL-first (Schema Definition Language), requires the schema be provided in advance, for instance, through some .gql file.

The main difference between these two approaches is that, in the code-first approach, the GraphQL schema is dynamic, adaptable to different users or applications. This suits WordPress, where a single site could power several applications (such as website and mobile app) and be customized for different clients. The GraphQL API makes this behavior explicit through the “custom endpoints” feature, which enables to create different endpoints, with access to different GraphQL schemas, for different users or applications.

To avoid performance hits, the schema is made static by caching it to disk or memory, and it is re-generated whenever a new plugin extending the schema is installed, or when the admin updates the settings.

Support for novel features

Another benefit of using the code-first approach is that it enables us to provide brand-new features that can be opted into, before these are supported by the GraphQL spec.

For instance, nested mutations have been requested for the spec but not yet approved. The GraphQL API complies with the spec, using types QueryRoot and MutationRoot to deal with queries and mutations respectively, as exposed in the standard schema. However, by enabling the opt-in “nested mutations” feature, the schema is transformed, and both queries and mutations will instead be handled by a single Root type, providing support for nested mutations.

Let’s see this novel feature in action. In this query, we first query the post through Root.post, then execute mutation Post.addComment on it and obtain the created comment object, and finally execute mutation Comment.reply on it and query some of its data (uncomment the first mutation to log the user in, as to be allowed to add comments):

# mutation {
#   loginUser(
#     usernameOrEmail:"test",
#     password:"pass"
#   ) {
#     id
#     name
#   }
# }
mutation {
  post(id:1459) {
    id
    title
    addComment(comment:"That's really beautiful!") {
      id
      date
      content
      author {
        id
        name
      }
      reply(comment:"Yes, it is!") {
        id
        date
        content
      }
    }
  }
}

Dynamic behavior

WordPress uses hooks (filters and actions) to modify behavior. Hooks are simple pieces of code that can override a value, or enable to execute a custom action, whenever triggered.

Is there an equivalent in GraphQL?

Directives to override functionality

Searching for a similar mechanism for GraphQL, I‘ve come to the conclusion that directives could be considered the equivalent to WordPress hooks to some extent: like a filter hook, a directive is a function that modifies the value of a field, thus augmenting some other functionality.

For instance, let’s say we retrieve a list of post titles with this query:

query {
  posts {
    title
  }
}

…which produces this response:

{
  "data": {
    "posts": [
      {
        "title": "Scheduled by Leo"
      },
      {
        "title": "COPE with WordPress: Post demo containing plenty of blocks"
      },
      {
        "title": "A lovely tango, not with leo"
      },
      {
      "title": "Hello world!"
      },
    ]
  }
}

These results are in English. How can we translate them to Spanish? With a directive @translate applied on field title (implemented through this directive resolver), which gets the value of the field as an input, calls the Google Translate API to translate it, and has its result override the original input, as in this query:

query {
  posts {
    title @translate(from:"en", to"es")
  }
}

…which produces this response:

{
  "data": {
    "posts": [
      {
        "title": "Programado por Leo"
      },
      {
        "title": "COPE con WordPress: publica una demostración que contiene muchos bloques"
      },
      {
        "title": "Un tango lindo, no con leo"
      },
      {
        "title": "¡Hola Mundo!"
      }
    ]
  }
}

Please notice how directives are unconcerned with who the input is. In this case, it was a Post.title field, but it could’ve been Post.excerpt, Comment.content, or any other field of type String. Then, resolving fields and overriding their value is cleanly decoupled, and directives are always reusable.

Directives to connect to third parties

As WordPress keeps steadily becoming the OS of the web (currently powering 39% of all sites, more than any other software), it also progressively increases its interactions with external services (think of Stripe for payments, Slack for notifications, AWS S3 for hosting assets, and others).

As we‘ve seen above, directives can be used to override the response of a field. But where does the new value come from? It could come from some local function, but it could perfectly well also originate from some external service (as for directive @translate we’ve seen earlier on, which retrieves the new value from the Google Translate API).

For this reason, GraphQL API has decided to make it easy for directives to communicate with external APIs, enabling those services to transform the data from the WordPress site when executing a query, such as for:

  • translation,
  • image compression,
  • sourcing through a CDN, and
  • sending emails, SMS and Slack notifications.

As a matter of fact, GraphQL API has decided to make directives as powerful as possible, by making them low-level components in the server’s architecture, even having the query resolution itself be based on a directive pipeline. This grants directives the power to perform authorizations, validations, and modification of the response, among others.

Localization

GraphQL servers using the SDL-first approach find it difficult to localize the information in the schema (the corresponding issue for the spec was created more than four years ago, and still has no resolution).

Using the code-first approach, though, the GraphQL API can localize the descriptions in a straightforward manner, through the __('some text', 'domain') PHP function, and the localized strings will be retrieved from a POT file corresponding to the region and language selected in the WordPress admin.

For instance, as we saw earlier on, this code localizes the field descriptions:

class UserFieldResolver extends AbstractDBDataFieldResolver
{
  public function getSchemaFieldDescription(
    TypeResolverInterface $typeResolver,
    string $fieldName
  ): ?string {
    $descriptions = [
      'username' => __("User's username handle", "graphql-api"),
      'email' => __("User's email", "graphql-api"),
      'url' => __("URL of the user's profile in the website", "graphql-api"),
    ];
    return $descriptions[$fieldName];
  }
}

User interfaces

The GraphQL ecosystem is filled with open source tools to interact with the service, including many provide the same user-friendly experience expected in WordPress.

Visualizing the GraphQL schema is done with GraphQL Voyager:

GraphQL Voyager enables us to interact with the schema, as to get a good grasp of how all entities in the application’s data model relate to each other.

This can prove particularly useful when creating our own CPTs, and checking out how and from where they can be accessed, and what data is exposed for them:

Interacting with the schema

Executing the query against the GraphQL endpoint is done with GraphiQL:

GraphiQL for the admin

However, this tool is not simple enough for everyone, since the user must have knowledge of the GraphQL query syntax. So, in addition, the GraphiQL Explorer is installed on top of it, as to compose the GraphQL query by clicking on fields:

GraphiQL with Explorer for the admin

Access control

WordPress provides different user roles (admin, editor, author, contributor and subscriber) to manage user permissions, and users can be logged-in the wp-admin (eg: the staff), logged-in the public-facing site (eg: clients), or not logged-in or have an account (any visitor). The GraphQL API must account for these, allowing to grant granular access to different users.

Granting access to the tools

The GraphQL API allows to configure who has access to the GraphiQL and Voyager clients to visualize the schema and execute queries against it:

  • Only the admin?
  • The staff?
  • The clients?
  • Openly accessible to everyone?

For security reasons, the plugin, by default, only provides access to the admin, and does not openly expose the service on the Internet.

In the images from the previous section, the GraphiQL and Voyager clients are available in the wp-admin, available to the admin user only. The admin user can grant access to users with other roles (editor, author, contributor) through the settings:

The admin user can grant access to users with other roles (editor, author, contributor) through the settings.

As to grant access to our clients, or anyone on the open Internet, we don’t want to give them access to the WordPress admin. Then, the settings enable to expose the tools under a new, public-facing URL (such as mywebsite.com/graphiql and mywebsite.com/graphql-interactive). Exposing these public URLs is an opt-in choice, explicitly set by the admin.

Granting access to the GraphQL schema

The WP REST API does not make it easy to customize who has access to some endpoint or field within an endpoint, since no user interface is provided and it must be accomplished through code.

The GraphQL API, instead, makes use of the metadata already available in the GraphQL schema to enable configuration of the service through a user interface (powered by the WordPress editor). As a result, non-technical users can also manage their APIs without touching a line of code.

Managing access control to the different fields (and directives) from the schema is accomplished by clicking on them and selecting, from a dropdown, which users (like those logged in or with specific capabilities) can access them.

Preventing conflicts

Namespacing helps avoid conflicts whenever two plugins use the same name for their types. For instance, if both WooCommerce and Easy Digital Downloads implement a type named Product, it would become ambiguous to execute a query to fetch products. Then, namespacing would transform the type names to WooCommerceProduct and EDDProduct, resolving the conflict.

The likelihood of such conflict arising, though, is not very high. So the best strategy is to have it disabled by default (as to keep the schema as simple as possible), and enable it only if needed.

If enabled, the GraphQL server automatically namespaces types using the corresponding PHP package name (for which all packages follow the PHP Standard Recommendation PSR-4). For instance, for this regular GraphQL schema:

Regular GraphQL schema

…with namespacing enabled, Post becomes PoPSchema_Posts_Post, Comment becomes PoPSchema_Comments_Comment, and so on.

Namespaced GraphQL schema

That’s all, folks

Both WordPress and GraphQL are captivating topics on their own, so I find the integration of WordPress and GraphQL greatly endearing. Having been at it for a few years now, I can say that designing the optimal way to have an old CMS manage content, and a new interface access it, is a challenge worth pursuing.

I could continue describing how the WordPress philosophy can influence the implementation of a GraphQL service running on WordPress, talking about it even for several hours, using plenty of material that I have not included in this write-up. But I need to stop… So I’ll stop now.

I hope this article has managed to provide a good overview of the whys and hows for satisfying the WordPress philosophy in GraphQL, as done by plugin GraphQL API for WordPress.


The post Rendering the WordPress philosophy in GraphQL appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

c++ lotto combinations

So i have to create a programm that reads 7-49 numbers and makes all posible combinations (6 number each) from the given numbers. Do you know how can i do this? I dont ask for the code ready but i cant think of a way i can create the combinations.