Document System Tutorial Part 13 - Custom AdminPage function

In this part, we will talk about creating a custom AdminPage function that checks the query and the UserID.

First of all, what does AdminPage function do? It fetches records from the database with some standard rules such as sorting data, multiples of, and setting a limit that can be used in pagination.

func(order string, asc bool, offset int, limit int, a interface{}, query interface{}, args ...interface{}) (err error)

Parameters:

order string: Is the field you want to specify in the database.

asc bool: true in ascending order, false in descending order.

offset int: Is the starting point of your list.

limit int: Is the number of records that you want to display in your application.

a interface{}: Is the variable where the model was initialized

query interface{}: Is an action that you want to perform with in your data list

args …interface{}: Is the series of arguments for query input

Here is an example:

Model: Ocean

Field to order: Name

Sort: Ascending

Index to start: 0

How many records: 10

Query: Where ID is ?

Argument: 5

The answer is uadmin.AdminPage(“name”, true, 0, 10, &Ocean, “id = ?”, 5).

Go to document.go inside the models folder and create a function named AdminPage that holds order with the data type string, asc with the data type bool, offset and limit with the type int, and a, query, and args… with the data type interface{}. args… means you can assign multiple values inside the function parameters.

// AdminPage !
func (d Document) AdminPage(order string, asc bool, offset int, limit int, a interface{}, query interface{}, args ...interface{}) (err error) {
    // Checks whether the starting point is less than 0
    if offset < 0 {
        offset = 0
    }

    // Converts the userID into uint because SQL Database reads the model ID
    // as uint
    userID := uint(0)

    // Converts the query into a string
    Q := fmt.Sprint(query)

    // Checks whether the string contains a query and a UserID
    if strings.Contains(Q, "user_id = ?") {
        // Prints the result for debugging
        uadmin.Trail(uadmin.DEBUG, "1")

        // Split the query part by part
        qParts := strings.Split(Q, " AND ")

        // Initialize tempArgs as an interface and tempQuery as a string
        tempArgs := []interface{}{}
        tempQuery := []string{}

        // Loop the query every part
        for i := range qParts {
            // Checks whether the specific query part is not equal to the
            // UserID value
            if qParts[i] != "user_id = ?" {
                // Append the arguments into the tempArgs variable
                tempArgs = append(tempArgs, args[i])

                // Append the specific query part into the tempQuery variable
                tempQuery = append(tempQuery, qParts[i])
            } else {
                // Prints the result for debugging
                uadmin.Trail(uadmin.DEBUG, "UserID: %d", args[i])

                // A type assertion that provides access to an interface
                // value's (args[i]) underlying concrete value (uint).
                userID, _ = (args[i]).(uint)
            }
        }
        // Concatenate the query to create a single string
        query = strings.Join(tempQuery, " AND ")

        // Assign tempArgs object into the args variable
        args = tempArgs
    }

    // Checks whether the userID is equal to 0
    if userID == 0 {
        // Prints the result for debugging
        uadmin.Trail(uadmin.DEBUG, "2")

        // Fetch the error by using AdminPage function
        err = uadmin.AdminPage(order, asc, offset, limit, a, query, args...)

        // Returns an error
        return err
    }

    // Initialize the user variable that calls the User model
    user := uadmin.User{}

    // Gets the ID of the user
    uadmin.Get(&user, "id = ?", userID)

    // Initialize docList and tempList that calls the Document model
    docList := []Document{}
    tempList := []Document{}

    // Loop execution
    for {
        // Fetch the error by using AdminPage function
        err = uadmin.AdminPage(order, asc, offset, limit, &tempList, query, args)
        uadmin.Trail(uadmin.DEBUG, "8: offset:%d, limit:%d", offset, limit)

        // Checks whether an error is not equal to nil
        if err != nil {
            // Prints the result for debugging
            uadmin.Trail(uadmin.DEBUG, "3")

            // Cast a model of interface as an array of Document then assigns
            // the docList object
            *a.(*[]Document) = docList

            // Return an error
            return err
        }

        // Checks whether the length of tempList is equal to 0
        if len(tempList) == 0 {
            // Prints the result for debugging
            uadmin.Trail(uadmin.DEBUG, "4")

            // Cast a model of interface as an array of Document then assigns
            // the docList object
            *a.(*[]Document) = docList

            // Prints the result for debugging
            uadmin.Trail(uadmin.DEBUG, "a: %#v", a)

            // Returns nothing
            return nil
        }

        // Loop the tempList values
        for i := range tempList {
            // Initialize p variable as Read permission
            p, _, _, _ := tempList[i].GetPermissions(user)

            // Checks whether the Document has read permission access
            if p {
                // Prints the result for debugging
                uadmin.Trail(uadmin.DEBUG, "5")

                // Append the tempList (Document) object to the docList
                // variable
                docList = append(docList, tempList[i])
            }

            // Checks whether the length of docList is equal to the limit
            if len(docList) == limit {
                // Prints the result for debugging
                uadmin.Trail(uadmin.DEBUG, "6")

                // Cast a model of interface as an array of Document then
                // assigns the docList object
                *a.(*[]Document) = docList

                // Returns nothing
                return nil
            }
        }

        // Add limit values to the offset variable
        offset += limit
    }
    // Cast a model of interface as an array of Document then assigns the
    // docList object
    *a.(*[]Document) = docList

    // Prints the result for debugging
    uadmin.Trail(uadmin.DEBUG, "7")

    // Returns nothing
    return nil
}

Click here to view our progress so far.

In the next part, we will discuss about displaying the permission status for each document records.